﻿///Nokia Firmware Cooker - tool for editing Nokia 5800 and 5530 firmwares.
///Copyright (C) 2010  Kalashnikov I.N.
///
///This program is free software; you can redistribute it and/or
///modify it under the terms of the GNU General Public License
///as published by the Free Software Foundation; either version 2
///of the License, or (at your option) any later version.
///
///This program is distributed in the hope that it will be useful,
///but WITHOUT ANY WARRANTY; without even the implied warranty of
///MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
///GNU General Public License for more details.
///
///You should have received a copy of the GNU General Public License
///along with this program; if not, write to the Free Software
///Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

//#define DEBUGMODE

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Xml.Serialization;
using Windows7.DesktopIntegration;
using Windows7.DesktopIntegration.WindowsForms;

namespace NokiaFirmwareCooker
{
    public partial class Form1 : Form
    {
        #region Fields
        public string firmwarePath;
        string defaultlanguage;
        public string effectsFolderPath;
        public string fontFolderPath;
        public string patchesFolderPath;
        public string startupSoundPath;
        public string startupSplashPath;
        public string shutdownSplashPath;
        public string menuFilePath;
        public string firmwareFilePath;
        ErrorLogger log = new ErrorLogger();
        ConfigInfo config;
        delegate void ModifingProgressCallback();
        object[] array;
        List<string> langs;
        //List<string> autorun;
        List<RadioButton> amr;
        ModifingProgressCallback del;
        Dictionary<string, string> LangToCode;
        Dictionary<string, string> CodeToLang;
        Dictionary<string, string> CodeToLangEng;
        double fwSize;
        double freeSpace = 33.0;
        int changesCount;
        TextWriter writer;
        bool isLoad = false;
        byte[] firstHeader;
        int headers;
        byte[] otherHeader = new byte[] { 84, 1, 23, 14, 0, 3, 0, 59, 16, 1, 0, 4, 0, 0, 7, 28, 4, 0, 95 };
        string playerConfStr;
        string galleryConfCStr;
        string galleryConfEStr;
        HelpProvider help;
        JumpListManager jumpListManager;
        bool isWinSeven;
        private string filepath;
        private string langCode;
        List<Button> buttons;
        List<string[]> symbols;
        List<int> layersPosition;
        byte[] bytes;
        bool isKeyboardLoad, isEngSimilarLoad;
        int keyboardLength;
        int ieroOnePos, ieroOneBigPos, numberPos, numberBigPos;
        PhoneModelProfile currentProfile;
        #endregion

        #region Path constants
        const string bootLangPath = "\\resource\\Bootdata\\languages.txt";
        const string starterBackgroundPath = "\\resource\\starter_background_apps.rsc";
        const string starterNonCriticalPath = "\\resource\\starter_non_critical_1.rsc";
        const string scriptInitPath = "\\private\\100059C9\\ScriptInit.txt";
        const string defBookmarksPath = "\\data\\BookmarkImportSample.txt";
        const string swipolicyPath = "\\system\\data\\swipolicy.ini";
        const string oviPluginPath = "\\sys\\bin\\oviimps_pbkkplugin.dll";
        const string privateConfigPath = "\\private\\10202be9\\";
        const string sbeConfigPath = "\\private\\10202d56\\sbeconfig.xml";
        string obeyFilePath = Application.StartupPath + "\\exe\\temp\\rofs2.obey";
        string rofs2FolderPath = Application.StartupPath + "\\rofs2\\";
        string rofs2NewImagePath = Application.StartupPath + "\\exe\\temp\\rofs2reb.img";
        string readImagePath = Application.StartupPath + "\\exe\\readimage.exe";
        string logFilePath = Application.StartupPath + "\\exe\\temp\\readImageLog.txt";
        string rofs2ImagePath = Application.StartupPath + "\\exe\\temp\\rofs2.img";
        string rofsBuildPath = Application.StartupPath + "\\exe\\rofsbuild.exe";
        readonly string yourFilesPath;
        #endregion

        public Form1()
        {
            InitializeComponent();
            CheckOsVersion();
            this.MaximumSize = this.Size;
            if (!Directory.Exists(Application.StartupPath + "\\Resources\\") || !Directory.Exists(Application.StartupPath + "\\exe\\"))
            {
                MessageBox.Show("Отсутствует папка с ресурсами! Приложение не может продолжить свою работу и будет закрыто.");
                System.Threading.Thread.Sleep(1000);
                Application.Exit();
            }
            InitHelp();
            InitProfiles();
            CreateFirmDirs();

            config = new ConfigInfo(this, this.contentTab, log);
            del = new ModifingProgressCallback(UpdateProgressBar);

            for (int i = 0; i < messageMenuItemCList.Items.Count; i++)
                messageMenuItemCList.SetItemChecked(i, true);
            usbTypeCombo.SelectedIndex = 0;
            accTypeCombo.SelectedIndex = 0;
            #region AMR Bitrate Radio Buttons Init
            amr = new List<RadioButton>();
            amr.Add(amrBitrate1);
            amr.Add(amrBitrate2);
            amr.Add(amrBitrate3);
            amr.Add(amrBitrate4);
            amr.Add(amrBitrate5);
            amr.Add(amrBitrate6);
            amr.Add(amrBitrate7);
            amr.Add(amrBitrate8); 
            #endregion
            homeScreensDefaultCombo.SelectedItem = (object)"Панель контактов";

            #region Buttons init
            buttons = new List<Button>();
            buttons.Add(button1);
            buttons.Add(button2);
            buttons.Add(button3);
            buttons.Add(button4);
            buttons.Add(button5);
            buttons.Add(button6);
            buttons.Add(button7);
            buttons.Add(button8);
            buttons.Add(button9);
            buttons.Add(button10);
            buttons.Add(button11);
            buttons.Add(button12);
            buttons.Add(button13);
            buttons.Add(button14);
            buttons.Add(button15);
            buttons.Add(button16);
            buttons.Add(button17);
            buttons.Add(button18);
            buttons.Add(button19);
            buttons.Add(button20);
            buttons.Add(button21);
            buttons.Add(button22);
            buttons.Add(button23);
            buttons.Add(button24);
            buttons.Add(button25);
            buttons.Add(button26);
            buttons.Add(button27);
            buttons.Add(button28);
            buttons.Add(button29);
            buttons.Add(button30);
            buttons.Add(button31);
            buttons.Add(button32);
            buttons.Add(button33);
            #endregion

            #region Config load
            if (File.Exists(Application.StartupPath + "\\Config\\cb.dat") &&
                    File.Exists(Application.StartupPath + "\\Config\\cmb.dat") &&
                    File.Exists(Application.StartupPath + "\\Config\\tb.dat") &&
                    File.Exists(Application.StartupPath + "\\Config\\rb.dat") &&
                    File.Exists(Application.StartupPath + "\\Config\\p.dat") &&
                    File.Exists(Application.StartupPath + "\\Config\\nud.dat"))
                loadConfigToolStripMenuItem.Enabled = true; 
            #endregion

            yourFilesPath = Application.StartupPath + "\\YourFiles\\";
        }

        private void InitHelp()
        {
            help = new HelpProvider();
            help.SetShowHelp(copyOwnFilesCB, true);
            help.SetHelpString(copyOwnFilesCB, "Отметьте галочку \"Копировать свои файлы в прошивку\", если хотите копировать какие-нибудь свои файлы в прошивку (например заставки, мелодии или программу вшить какую захотите). Свои файлы бросать в папку Your Files, которая лежит вместе с этой программой, с сохранением структуры. Сначала бросайте файлы, затем ставьте галочку!");
            help.SetShowHelp(editKeyboardCB, true);
            help.SetHelpString(editKeyboardCB, "Отметьте эту галочку, чтобы получить возможность редактировать раскладки виртуальных qwerty-клавиатур (малая и полноэкранная).");
            help.SetShowHelp(saveKeyboardButton, true);
            help.SetHelpString(saveKeyboardButton, "Нажмите эту кнопку, чтобы сохранить текущие изменения в клавиатуре. Иначе при смене редактируемого языка клавиатуры все изменения будут сброшены!");
            help.SetShowHelp(keyboardLangsCombo, true);
            help.SetHelpString(keyboardLangsCombo, "В данном выпадающем списке вы можете выбрать языковую раскладку для редактирования.");
            help.SetShowHelp(softList, true);
            help.SetHelpString(softList, "Список программ, выбранных вами для вшивания в прошивку");
        }

        private void InitProfiles()
        {
            if (File.Exists(Application.StartupPath + "\\Config\\Profiles.xml"))
            {
                StreamReader reader = new StreamReader(Application.StartupPath + "\\Config\\Profiles.xml", Encoding.UTF8);
                string temp = reader.ReadToEnd();
                reader.Close();
                XElement xml = XElement.Parse(temp);

                var perfomanceProfilesList = from profile in xml.Descendants("perfomance")
                                             select new PerfomanceProfile
                                             {
                                                 bufferPercent = Convert.ToDecimal(profile.Attribute("buffer").Value),
                                                 cleanAutorun = Convert.ToBoolean(profile.Attribute("clean_autorun").Value),
                                                 cpuTime = Convert.ToDecimal(profile.Attribute("cpu_time").Value),
                                                 disableCameraAppCaching = Convert.ToBoolean(profile.Attribute("disable_camera_app_caching").Value),
                                                 effectsDiff = Convert.ToDecimal(profile.Attribute("effects_diff").Value),
                                                 fps = Convert.ToDecimal(profile.Attribute("fps").Value),
                                                 heapSize = Convert.ToDecimal(profile.Attribute("heap_size").Value),
                                                 increaseDiskCacheSize = Convert.ToBoolean(profile.Attribute("increase_disk_cache_size").Value),
                                                 maxCacheObjects = Convert.ToDecimal(profile.Attribute("max_cache_objects").Value),
                                                 progLatency = Convert.ToDecimal(profile.Attribute("prog_latency").Value),
                                                 resCacheSize = Convert.ToDecimal(profile.Attribute("res_cache_size").Value),
                                                 sysCacheOnC = Convert.ToBoolean(profile.Attribute("sys_cache_on_c").Value),
                                                 sysCacheSize = Convert.ToDecimal(profile.Attribute("sys_cache_size").Value),
                                                 profileName = profile.Attribute("name").Value
                                             };
                foreach (var profile in perfomanceProfilesList)
                    perfProfileCombo.Items.Add(profile);
                ApplyPerfomanceProfile(0);

                var kineticProfilesList = from profile in xml.Descendants("kinetic")
                                          select new KineticProfile
                                          {
                                              one = Convert.ToDecimal(profile.Attribute("one").Value),
                                              two = Convert.ToDecimal(profile.Attribute("two").Value),
                                              three = Convert.ToDecimal(profile.Attribute("three").Value),
                                              four = Convert.ToDecimal(profile.Attribute("four").Value),
                                              five = Convert.ToDecimal(profile.Attribute("five").Value),
                                              six = Convert.ToDecimal(profile.Attribute("six").Value),
                                              seven = Convert.ToDecimal(profile.Attribute("seven").Value),
                                              eight = Convert.ToDecimal(profile.Attribute("eight").Value),
                                              profileName = profile.Attribute("name").Value
                                          };
                foreach (var profile in kineticProfilesList)
                    kineticProfileCombo.Items.Add(profile);
                ApplyKineticProfile(0);

                var phoneModelProfilesList = from profile in xml.Descendants("model")
                                             select new PhoneModelProfile
                                             {
                                                 autorun = profile.Attribute("auto").Value,
                                                 phoneUi = profile.Attribute("phoneui").Value,
                                                 rus = profile.Attribute("rus").Value,
                                                 ukr = profile.Attribute("ua").Value,
                                                 profileName = profile.Attribute("name").Value
                                             };
                foreach (var profile in phoneModelProfilesList)
                    phoneModelCombo.Items.Add(profile);
                phoneModelCombo.SelectedIndex = 0;
            }
            else
                log.AddError("Отсутствует файл: " + Application.StartupPath + "\\Config\\Profiles.xml", new FileNotFoundException("File not found!", Application.StartupPath + "\\Config\\Profiles.xml"));
        }

        private void PrepaireKeyboardFile(string filename)
        {
            FileStream file = new FileStream(filename, FileMode.Open);
            bytes = new byte[file.Length];
            file.Read(bytes, 0, (int)file.Length);
            file.Close();
            layersPosition = new List<int>();
            for (int i = 0; i < bytes.Length; i++)
            {
                if ((bytes[i] == 171 && bytes[i - 1] == 1 && bytes[i - 2] == 0 && bytes[i - 3] == 33) || (bytes[i] == 171 && bytes[i - 1] == 1 && bytes[i - 2] == 0 && bytes[i - 3] == 30))
                    layersPosition.Add(i + 1);
            }
            LangAdaptation();
            symbols = new List<string[]>();
            foreach (int i in layersPosition)
            {
                string[] buf = new string[keyboardLength];
                for (int j = 0; j < keyboardLength; j++)
                {
                    byte[] symbol = new byte[] { bytes[i + (18 * j)], bytes[i + (18 * j) + 1] };
                    buf[j] = UnicodeEncoding.Unicode.GetString(symbol);
                }
                symbols.Add(buf);
            }
            isKeyboardLoad = true;
            generalRadio.Checked = true;
            string[] sym;
            if (generalRadio.Checked)
                sym = symbols[0];
            else if (generalBigRadio.Checked)
                sym = symbols[1];
            else if (numbersRadio.Checked)
                sym = symbols[numberPos];
            else if (numbersBigRadio.Checked)
                sym = symbols[numberBigPos];
            else if (ieroOneRadio.Checked)
                sym = symbols[ieroOnePos];
            else if (ieroOneBigRadio.Checked)
                sym = symbols[ieroOneBigPos];
            else if (ieroTwoRadio.Checked)
                sym = symbols[6];
            else if (ieroTwoBigRadio.Checked)
                sym = symbols[7];
            else if (ieroThreeRadio.Checked)
                sym = symbols[8];
            else
                sym = symbols[9];
            int k = 0;
            foreach (Button b in buttons)
            {
                if (k < keyboardLength)
                    b.Text = sym[k];
                k++;
            }
        }

        private void ApplyChangesToTheKeyboardFile(string filename)
        {
            int k = 0;
            foreach (int i in layersPosition)
            {
                string[] buf = symbols[k];
                for (int j = 0; j < keyboardLength; j++)
                {
                    byte[] symbol = Encoding.Unicode.GetBytes(buf[j]);
                    bytes[i + (18 * j)] = symbol[0];
                    bytes[i + (18 * j) + 1] = symbol[1];
                    bytes[i + (18 * j) + 2] = symbol[0];
                    bytes[i + (18 * j) + 3] = symbol[1];
                }
                k++;
            }
            FileStream file = new FileStream(filename, FileMode.Create);
            file.Write(bytes, 0, bytes.Length);
            file.Close();
        }

        private void LangAdaptation()
        {
            if (layersPosition.Count > 8)
            {
                keyboardLength = 30;
                ieroOnePos = 4;
                ieroOneBigPos = 5;
                numberPos = 2;
                numberBigPos = 3;
                ieroTwoRadio.Enabled = true;
                ieroTwoBigRadio.Enabled = true;
                ieroThreeRadio.Enabled = true;
                ieroThreeBigRadio.Enabled = true;
                if (isEngSimilarLoad == false)
                {
                    for (int i = 10; i < 20; i++)
                        buttons[i].Location = buttons[i + 1].Location;
                    for (int i = 20; i < 30; i++)
                        buttons[i].Location = buttons[i + 2].Location;
                    button31.Enabled = false;
                    button31.Location = new Point(394, 13);
                    button31.Text = string.Empty;
                    button32.Enabled = false;
                    button32.Location = new Point(394, 51);
                    button32.Text = string.Empty;
                    button33.Enabled = false;
                    button33.Text = string.Empty;
                    isEngSimilarLoad = true;
                }
            }
            else
            {
                keyboardLength = 33;
                ieroOnePos = 2;
                ieroOneBigPos = 3;
                numberPos = 4;
                numberBigPos = 5;
                ieroTwoRadio.Enabled = false;
                ieroTwoBigRadio.Enabled = false;
                ieroThreeRadio.Enabled = false;
                ieroThreeBigRadio.Enabled = false;
                if (isEngSimilarLoad)
                {
                    button31.Enabled = true;
                    button31.Location = new Point(318, 89);
                    button32.Enabled = true;
                    button32.Location = new Point(356, 89);
                    button33.Enabled = true;
                    for (int i = 29; i > 21; i--)
                        buttons[i].Location = buttons[i - 2].Location;
                    buttons[21].Location = new Point(394, 51);
                    for (int i = 20; i > 10; i--)
                        buttons[i].Location = buttons[i - 1].Location;
                    button11.Location = new Point(394, 13);
                }
                isEngSimilarLoad = false;
            }
        }

        private void ApplyChanges()
        {
            if (!string.IsNullOrEmpty(button1.Text))
            {
                string[] sym;
                if (generalRadio.Checked)
                    sym = symbols[0];
                else if (generalBigRadio.Checked)
                    sym = symbols[1];
                else if (numbersRadio.Checked)
                    sym = symbols[numberPos];
                else if (numbersBigRadio.Checked)
                    sym = symbols[numberBigPos];
                else if (ieroOneRadio.Checked)
                    sym = symbols[ieroOnePos];
                else if (ieroOneBigRadio.Checked)
                    sym = symbols[ieroOneBigPos];
                else if (ieroTwoRadio.Checked)
                    sym = symbols[6];
                else if (ieroTwoBigRadio.Checked)
                    sym = symbols[7];
                else if (ieroThreeRadio.Checked)
                    sym = symbols[8];
                else
                    sym = symbols[9];
                int k = 0;
                foreach (Button b in buttons)
                {
                    if (k < keyboardLength)
                        sym[k] = b.Text;
                    k++;
                }
                if (generalRadio.Checked)
                    symbols[0] = sym;
                else if (generalBigRadio.Checked)
                    symbols[1] = sym;
                else if (numbersRadio.Checked)
                    symbols[numberPos] = sym;
                else if (numbersBigRadio.Checked)
                    symbols[numberBigPos] = sym;
                else if (ieroOneRadio.Checked)
                    symbols[ieroOnePos] = sym;
                else if (ieroOneBigRadio.Checked)
                    symbols[ieroOneBigPos] = sym;
                else if (ieroTwoRadio.Checked)
                    symbols[6] = sym;
                else if (ieroTwoBigRadio.Checked)
                    symbols[7] = sym;
                else if (ieroThreeRadio.Checked)
                    symbols[8] = sym;
                else
                    symbols[9] = sym;
            }
        }

        private void CheckOsVersion()
        {
            OperatingSystem os = Environment.OSVersion;
            Version ver = os.Version;
            if (ver.Major >= 6 && ver.Minor >= 1)
                isWinSeven = true;
            else
                isWinSeven = false;
        }

        protected override void WndProc(ref Message m)
        {
            if (isWinSeven)
            {
                if (m.Msg == Windows7Taskbar.TaskbarButtonCreatedMessage)
                {
                    jumpListManager = WindowsFormsExtensions.CreateJumpListManager(this);
                    jumpListManager.UserRemovedItems += (o, e) =>
                    {
                        e.CancelCurrentOperation = false;
                    };

                    jumpListManager.AddCustomDestination(new ShellLink
                    {
                        Path = Path.Combine(Application.StartupPath, "changes.txt"),
                        Title = "Список изменений в прошивке",
                        Category = "Документы",
                        IconLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "notepad.exe"),
                        IconIndex = 0
                    });

                    jumpListManager.AddCustomDestination(new ShellLink
                    {
                        Path = Path.Combine(Application.StartupPath, "license.txt"),
                        Title = "License",
                        Category = "Документы",
                        IconLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "notepad.exe"),
                        IconIndex = 0
                    });

                    jumpListManager.AddCustomDestination(new ShellLink
                    {
                        Path = Path.Combine(Application.StartupPath, "rofs2"),
                        Title = "Папка с ROFS2",
                        Category = "Папки",
                        IconLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "shell32.dll"),
                        IconIndex = 3
                    });

                    jumpListManager.AddCustomDestination(new ShellLink
                    {
                        Path = Path.Combine(Application.StartupPath, "YourFiles"),
                        Title = "Папка с вашими файлами",
                        Category = "Папки",
                        IconLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "shell32.dll"),
                        IconIndex = 3
                    });

                    jumpListManager.Refresh();
                }
            }
            base.WndProc(ref m);
        }

        [Conditional("DEBUGMODE")]
        private void WriteLog(List<string> txt)
        {
            DateTime now = DateTime.Now;
            File.AppendAllText("\\log.txt", "-------------- " + now.ToString() + " --------------" + Environment.NewLine);
            foreach (string s in txt)
                File.AppendAllText("\\log.txt", s + Environment.NewLine);
        }

        [Conditional("DEBUGMODE")]
        private void WriteLog(string[] txt)
        {
            DateTime now = DateTime.Now;
            File.AppendAllText("\\log.txt", "-------------- " + now.ToString() + " --------------" + Environment.NewLine);
            foreach (string s in txt)
                File.AppendAllText("\\log.txt", s + Environment.NewLine);
        }

        [Conditional("DEBUGMODE")]
        private void WriteLog(string txt)
        {
            DateTime now = DateTime.Now;
            File.AppendAllText("\\log.txt", "-------------- " + now.ToString() + " --------------" + Environment.NewLine);
            File.AppendAllText("\\log.txt", txt + Environment.NewLine);
        }

        private void CreateFirmDirs()
        {
            if (!Directory.Exists(Application.StartupPath + "\\rofs2\\"))
                Directory.CreateDirectory(Application.StartupPath + "\\rofs2\\");
            if (!Directory.Exists(Application.StartupPath + "\\exe\\temp\\"))
                Directory.CreateDirectory(Application.StartupPath + "\\exe\\temp\\");
            if (!Directory.Exists(Application.StartupPath + "\\temp\\"))
                Directory.CreateDirectory(Application.StartupPath + "\\temp\\");
            if (!Directory.Exists(Application.StartupPath + "\\YourFiles\\"))
            {
                Directory.CreateDirectory(Application.StartupPath + "\\YourFiles\\");
                Directory.CreateDirectory(Application.StartupPath + "\\YourFiles\\data\\");
                Directory.CreateDirectory(Application.StartupPath + "\\YourFiles\\private\\");
                Directory.CreateDirectory(Application.StartupPath + "\\YourFiles\\private\\10202be9\\");
                Directory.CreateDirectory(Application.StartupPath + "\\YourFiles\\resource\\apps\\");
                Directory.CreateDirectory(Application.StartupPath + "\\YourFiles\\sys\\");
                Directory.CreateDirectory(Application.StartupPath + "\\YourFiles\\sys\\bin\\");
                Directory.CreateDirectory(Application.StartupPath + "\\YourFiles\\System\\data");
            }
            if (!Directory.Exists(Application.StartupPath + "\\Config\\"))
                Directory.CreateDirectory(Application.StartupPath + "\\Config\\");
        }

        private void ApplyPerfomanceProfile(int index)
        {
            PerfomanceProfile profile = perfProfileCombo.Items[index] as PerfomanceProfile;
            bufferPercentNUD.Value = profile.bufferPercent;
            clearAutorunCB.Checked = profile.cleanAutorun;
            cpuTimeNUD.Value = profile.cpuTime;
            cameraCacheDisableCB.Checked = profile.disableCameraAppCaching;
            graphicEffectsComplexiyNUD.Value = profile.effectsDiff;
            fpsNUD.Value = profile.fps;
            heapSizeNUD.Value = profile.heapSize;
            increaseSysCacheCB.Checked = profile.increaseDiskCacheSize;
            maxCacheableItemsNUD.Value = profile.maxCacheObjects;
            appDelayNUD.Value = profile.progLatency;
            maxResourceCacheNUD.Value = profile.resCacheSize;
            if (profile.sysCacheOnC)
                cacheToCRadio.Checked = true;
            else
                cacheToERadio.Checked = true;
            maxSysCacheSizeNUD.Value = profile.sysCacheSize;
            perfProfileCombo.SelectedItem = perfProfileCombo.Items[index];
        }

        private void ApplyKineticProfile(int index)
        {
            KineticProfile profile = kineticProfileCombo.Items[index] as KineticProfile;
            kinetic1.Value = profile.one;
            kinetic2.Value = profile.two;
            kinetic3.Value = profile.three;
            kinetic4.Value = profile.four;
            kinetic5.Value = profile.five;
            kinetic6.Value = profile.six;
            kinetic7.Value = profile.seven;
            kinetic8.Value = profile.eight;
            kineticProfileCombo.SelectedItem = kineticProfileCombo.Items[index];
        }

        /// <summary>
        /// Копировать файл из папки Resource в папку с прошивкой
        /// </summary>
        /// <param name="sourcefn">Файл, который нужно копировать</param>
        /// <param name="destinfn">Файл назначения</param>
        private void CopyFile(string sourcefn, string destinfn)
        {
            FileInfo fn = new FileInfo(Application.StartupPath + "\\Resources\\" + sourcefn);
            fn.CopyTo(firmwarePath + destinfn, true);
        }

        /// <summary>
        /// Возвращает размер папки в байтах
        /// </summary>
        /// <param name="dir">Папка</param>
        /// <returns>Размер в байтах</returns>
        public long DirSize(DirectoryInfo dir)
        {
            long size = 0;
            // Add file sizes.
            FileInfo[] fis = dir.GetFiles();
            foreach (FileInfo fi in fis)
            {
                size += fi.Length;
            }
            // Add subdirectory sizes.
            DirectoryInfo[] dis = dir.GetDirectories();
            foreach (DirectoryInfo di in dis)
            {
                size += DirSize(di);
            }
            return size;
        }

        /// <summary>
        /// Копирование содержимого папки с сохранением структуры в прошивку
        /// </summary>
        /// <param name="dir">Полный путь к папке, из которой копировать</param>
        /// <param name="stopDir">Имя папки, из которой будет произведено копирование с сохранением структуры</param>
        public void CopyDir(DirectoryInfo dir, string stopDir)
        {
            FileInfo[] fis = dir.GetFiles();
            foreach (FileInfo fi in fis)
            {
                string[] dirs = fi.DirectoryName.Split(new char[] { '\\' });
                int i = 0;
                string cmp = "\\";
                do
                    i++;
                while (!dirs[i].Equals(stopDir));
                ++i;
                while (i < dirs.Length)
                {
                    cmp += dirs[i] + "\\";
                    i++;
                }
                if (!Directory.Exists(firmwarePath + cmp))
                    Directory.CreateDirectory(firmwarePath + cmp);
                fi.CopyTo(firmwarePath + cmp + fi.Name, true);
            }
            DirectoryInfo[] dis = dir.GetDirectories();
            foreach (DirectoryInfo di in dis)
                CopyDir(di, stopDir);
        }
        /// <summary>
        /// Копирование содержимого папки с сохранением структуры
        /// </summary>
        /// <param name="dir">Полный путь к папке, из которой копировать</param>
        /// <param name="stopDir">Имя папки, из которой будет произведено копирование с сохранением структуры</param>
        /// <param name="path">Полный путь к папке, в которую копировать</param>
        public void CopyDir(DirectoryInfo dir, string stopDir, string path)
        {
            FileInfo[] fis = dir.GetFiles();
            foreach (FileInfo fi in fis)
            {
                string[] dirs = fi.DirectoryName.Split(new char[] { '\\' });
                int i = 0;
                string cmp = "\\";
                do
                    i++;
                while (!dirs[i].Equals(stopDir));
                ++i;
                while (i < dirs.Length)
                {
                    cmp += dirs[i] + "\\";
                    i++;
                }
                if (!Directory.Exists(path + cmp))
                    Directory.CreateDirectory(path + cmp);
                fi.CopyTo(path + cmp + fi.Name, true);
            }
            DirectoryInfo[] dis = dir.GetDirectories();
            foreach (DirectoryInfo di in dis)
                CopyDir(di, stopDir, path);
        }

        /// <summary>
        /// Отсекает c_ и e_ в названии папки
        /// </summary>
        /// <param name="dir">Корневая папка</param>
        public void NormDir(DirectoryInfo dir)
        {
            DirectoryInfo[] dis = dir.GetDirectories();
            foreach (DirectoryInfo di in dis)
            {
                string tmp = di.Name.Substring(0, 2);
                string dirName = di.Name.Substring(2);
                if (tmp.Equals("c_") || tmp.Equals("e_"))
                {
                    string path = di.FullName;
                    path = path.Substring(0, path.LastIndexOf('\\') + 1);
                    path += dirName + "\\";
                    CopyDir(di, di.Name, path);
                    di.Delete(true);
                }
                else
                    NormDir(di);
            }
        }

        public void GetFileList(DirectoryInfo dir, ref List<string> list)
        {
            FileInfo[] fis = dir.GetFiles();
            foreach (FileInfo fi in fis)
                list.Add(fi.FullName);
            DirectoryInfo[] dis = dir.GetDirectories();
            foreach (DirectoryInfo di in dis)
                GetFileList(di, ref list);
        }

        private string[] ReadScriptInit()
        {
            if (File.Exists(firmwarePath + scriptInitPath))
            {
                StreamReader reader = new StreamReader(firmwarePath + scriptInitPath);
                List<string> si = new List<string>();
                while (!reader.EndOfStream)
                    si.Add(reader.ReadLine());
                string[] result = new string[si.Count + 1];
                for (int i = 0; i < si.Count; i++)
                    result[i] = si[i];
                result[si.Count] = string.Empty;
                reader.Close();
                return result;
            }
            else
            {
                log.AddError("Отсутствует файл: " + firmwarePath + scriptInitPath, new FileNotFoundException("File not found!", firmwarePath + scriptInitPath));
            }
            return new string[] { "null" };
        }

        private string[] ReadHiddenAppsUids()
        {
            if (File.Exists(firmwarePath + privateConfigPath + "101F8847.txt"))
            {
                string temp = ReadDataValueFromConfigFile("101F8847.txt", "0x8");
                if (temp.Length > 7)
                {
                    string[] uids = temp.Split(new char[] { ',' });
                    return uids;
                }
                else
                    return new string[] { string.Empty };
            }
            else
            {
                log.AddError("Отсутствует файл: " + firmwarePath + privateConfigPath + "101F8847.txt", new FileNotFoundException("File not found!", firmwarePath + privateConfigPath + "101F8847.txt"));
            }
            return new string[] { string.Empty };
        }

        private string[] ReadScanDirs(string strnum, string confpath, char divsymbol)
        {
            if (File.Exists(firmwarePath + privateConfigPath + confpath))
            {
                string temp = ReadDataValueFromConfigFile(confpath, strnum);
                switch (confpath)
                {
                    case "101FFCD2.txt":
                        playerConfStr = temp;
                        break;
                    case "102828AC.txt":
                        if (strnum.Equals("0x1"))
                            galleryConfCStr = temp;
                        else
                            galleryConfEStr = temp;
                        break;
                    default:
                        break;
                }
                string[] dirs = temp.Split(new char[] { divsymbol });
                return dirs;
            }
            else
            {
                log.AddError("Отсутствует файл: " + firmwarePath + privateConfigPath + confpath, new FileNotFoundException("File not found!", firmwarePath + privateConfigPath + confpath));
            }
            return new string[] { string.Empty };
        }

        private string ReadDataValueFromConfigFile(string confFileName, string strnum)
        {
            if (File.Exists(firmwarePath + privateConfigPath + confFileName))
            {
                string path = firmwarePath + privateConfigPath + confFileName;
                TextReader reader = new StreamReader(path);
                string str;
                string value = string.Empty;
                while ((str = reader.ReadLine()) != "[Main]") ;
                while ((str = reader.ReadLine()) != null)
                {
                    if (str.Substring(0, str.IndexOf(' ')).Equals(strnum, StringComparison.CurrentCultureIgnoreCase))
                    {
                        value = str.Split(new char[] { ' ' })[2];
                        string type = str.Split(new char[] { ' ' })[1];
                        //Если значение строковое, то обрезаем кавычки по краям
                        if (type.Equals("string"))
                        {
                            value = value.Substring(0, value.Length - 1);
                            value = value.Substring(1);
                        }
                    }
                }
                reader.Close();
                return value;
            }
            else
            {
                log.AddError("Отсутствует файл: " + firmwarePath + privateConfigPath + confFileName, new FileNotFoundException("File not found!", firmwarePath + privateConfigPath + confFileName));
                return "null";
            }
        }

        private void LoadStarterFile(string path)
        {
            //if (File.Exists(firmwarePath + path))
            //{
            //    StreamReader reader = new StreamReader(firmwarePath + path);
            //    bool start = false;
            //    StringBuilder bld = new StringBuilder();
            //    while (!reader.EndOfStream)
            //    {
            //        char temp = Convert.ToChar(Char.ConvertFromUtf32(reader.Read()));
            //        if (char.IsLetterOrDigit(temp) || temp.Equals(':') || temp.Equals('\\') || temp.Equals('.') || temp.Equals('$') || temp.Equals('_'))
            //        {
            //            start = true;
            //            bld.Append(temp);
            //        }
            //        else
            //        {
            //            if (start)
            //            {
            //                start = false;
            //                if (bld.Length > 4)
            //                {
            //                    string tmp = bld.ToString();
            //                    int len = tmp.Length - 1;
            //                    if (tmp[len] == '.')
            //                        tmp = tmp.Substring(0, len);
            //                    len = tmp.Length - 1;
            //                    if (tmp[len] == '$')
            //                        tmp = tmp.Substring(0, len) + "e";
            //                    if (!tmp.Equals("AllReasons") && !tmp.Equals("FirstBootup") && !tmp.Equals("FirmwareUpdate"))
            //                        autorun.Add(tmp);
            //                }
            //                bld = new StringBuilder();
            //            }
            //        }
            //    }
            //    reader.Close();
            //}
            //else
            //{
            //    log.AddError("Отсутствует файл: " + firmwarePath + path);
            //}
        }

        private void LoadLangSupportByFirmware()
        {
            if (File.Exists(firmwarePath + bootLangPath))
            {
                StreamReader reader = new StreamReader(firmwarePath + bootLangPath);
                langs = new List<string>();
                string temp;
                while (!reader.EndOfStream)
                {
                    int i = 0;
                    temp = reader.ReadLine();
                    if (!string.IsNullOrEmpty(temp))
                        langs.Add(ParseLangList(temp));
                    i++;
                }
                reader.Close();
            }
            else
            {
                log.AddError("Отсутствует файл: " + firmwarePath + bootLangPath, new FileNotFoundException("File not found!", firmwarePath + privateConfigPath + bootLangPath));
            }
        }

        private string ParseLangList(string s)
        {
            if (s.Contains(",d"))
            {
                s = s.Remove(2);
                defaultlanguage = s;
                return s;
            }
            return s;
        }

        private void DetectLangList()
        {
            if (File.Exists(Application.StartupPath + "\\Config\\LangRU.txt"))
            {
                TextReader reader = new StreamReader(Application.StartupPath + "\\Config\\LangRU.txt", Encoding.UTF8);
                string temp;
                LangToCode = new Dictionary<string, string>();
                CodeToLang = new Dictionary<string, string>();
                while ((temp = reader.ReadLine()) != null)
                {
                    string code = temp.Substring(0, temp.IndexOf(' '));
                    string lang = temp.Substring(temp.IndexOf(' ') + 1);
                    LangToCode.Add(lang, code);
                    CodeToLang.Add(code, lang);
                }
                reader.Close(); 
            }
            else
            {
                log.AddError("Отсутствует файл: " + Application.StartupPath + "\\Config\\LangRU.txt", new FileNotFoundException("File not found!", Application.StartupPath + "\\Config\\LangRU.txt"));
            }
            if (File.Exists(Application.StartupPath + "\\Config\\LangEN.txt"))
            {
                TextReader reader = new StreamReader(Application.StartupPath + "\\Config\\LangEN.txt");
                string temp;
                CodeToLangEng = new Dictionary<string, string>();
                while ((temp = reader.ReadLine()) != null)
                {
                    string code = temp.Substring(0, temp.IndexOf(' '));
                    string lang = temp.Substring(temp.IndexOf(' ') + 1);
                    CodeToLangEng.Add(code, lang);
                }
                reader.Close(); 
            }
            else
            {
                log.AddError("Отсутствует файл: " + Application.StartupPath + "\\Config\\LangEN.txt", new FileNotFoundException("File not found!", Application.StartupPath + "\\Config\\LangEN.txt"));
            }
        }

        private string ConvertLang(string s)
        {
            if (s.Length <= 3)
                return CodeToLang[s];
            else
                return LangToCode[s];
        }

        private void InitLang()
        {
            array = new object[langs.Count];
            for (int i = 0; i < langs.Count; i++)
                array[i] = (object)ConvertLang(langs[i]);
            defLangCombo.Items.AddRange(array);
            helpLangCList.Items.AddRange(array);
            phoneLangCList.Items.AddRange(array);
            inputLangCList.Items.AddRange(array);
            defLangCombo.SelectedItem = (object)ConvertLang(defaultlanguage);
            defLangCombo.SelectionChangeCommitted += new EventHandler(defLangCombo_SelectionChangeCommitted);
            for (int i = 0; i < inputLangCList.Items.Count; i++)
                inputLangCList.SetItemChecked(i, true);
            for (int i = 0; i < phoneLangCList.Items.Count; i++)
                phoneLangCList.SetItemChecked(i, true);
            for (int i = 0; i < helpLangCList.Items.Count; i++)
                helpLangCList.SetItemChecked(i, true);
        }

        private void InitBootList()
        {
            /*foreach (string s in autorun)
                autorunCList.Items.Add((object)s, false);*/
        }

        private void defLangCombo_SelectionChangeCommitted(object sender, EventArgs e)
        {
            Dictionary<string, bool> langs = new Dictionary<string, bool>();
            for (int i = 0; i < phoneLangCList.Items.Count; i++)
                langs[Convert.ToString(phoneLangCList.Items[i])] = phoneLangCList.GetItemChecked(i);
            if (langs[Convert.ToString(defLangCombo.SelectedItem)] == false)
            {
                defLangCombo.SelectedItem = phoneLangCList.CheckedItems[0];
                MessageBox.Show("Нельзя выбрать в качестве языка по умолчанию - язык, который собираетесь удалить!");
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void PutStringArrayIntoListBox(string[] array, ListBox list)
        {
            foreach (string s in array)
            {
                if (!string.IsNullOrEmpty(s))
                    list.Items.Add(s);
            }
        }

        private string[] TakeStringArrayFromListBox(ListBox list)
        {
            string[] array = new string[list.Items.Count];
            int i = 0;
            foreach (object o in list.Items)
            {
                array[i] = o.ToString();
                i++;
            }
            return array;
        }

        private void ProgrammReset()
        {
            firmwarePath = string.Empty;
            cookToolStripMenuItem.Enabled = false;
            langs.Clear();
            LangToCode.Clear();
            CodeToLang.Clear();
            CodeToLangEng.Clear();
            defLangCombo.Items.Clear();
            helpLangCList.Items.Clear();
            phoneLangCList.Items.Clear();
            inputLangCList.Items.Clear();
            defThemeUidText.Text = string.Empty;
            hideAppUidList.Items.Clear();
            playerScanList.Items.Clear();
            galleryScanClist.Items.Clear();
            galleryScanElist.Items.Clear();
            scriptInitList.Lines = new string[] { string.Empty };
            fwSize = 0.0;
            fwSizeText.Text = "Испол. места: 0 МБ";
            config = new ConfigInfo(this, this.contentTab, log);
            contentTab.Enabled = false;
        }

        private void openFolderToolStripMenuItem_Click(object sender, EventArgs e)
        {
            currentOperationText.Text = "Текущая операция: Открываю папку с прошивкой";
            if (isLoad)
            {
                isLoad = false;
                ProgrammReset();
            }
            if (openFolderDialog.ShowDialog() == DialogResult.OK)
            {
                firmwarePath = openFolderDialog.SelectedPath;
                if (Directory.Exists(firmwarePath + "\\private\\"))
                {
                    isLoad = true;
                    cookToolStripMenuItem.Enabled = true;
                    LoadLangSupportByFirmware();
                    DetectLangList();
                    InitLang();
                    defThemeUidText.Text = ReadDataValueFromConfigFile("101F876F.txt", "0x14");
                    PutStringArrayIntoListBox(ReadHiddenAppsUids(), hideAppUidList);
                    PutStringArrayIntoListBox(ReadScanDirs("0x1", "101FFCD2.txt", '|'), playerScanList);
                    PutStringArrayIntoListBox(ReadScanDirs("0x1", "102828AC.txt", ';'), galleryScanClist);
                    PutStringArrayIntoListBox(ReadScanDirs("0x2", "102828AC.txt", ';'), galleryScanElist);
                    scriptInitList.Lines = ReadScriptInit();
                    fwSize = ((double)DirSize(new DirectoryInfo(firmwarePath)) / 1024) / 1024;
                    fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
                    config.InitConfigInfo();
                    contentTab.Enabled = true;
                    currentOperationText.Text = "Текущая операция: *бездействие*";
                    if (log.GetErrorCount() > 0)
                        MessageBox.Show("При открытии произошли следующие ошибки:" + Environment.NewLine + Environment.NewLine + log.ToString());
                }
                else
                    MessageBox.Show("Вы открыли неверную папку! Попробуйте еще раз.");
            }
        }

        private void ChangeKeyboard(string lcode)
        {
            isKeyboardLoad = false;
            this.filepath = firmwarePath + "\\resource\\plugins\\peninputvkbwindowconfiginfo_" + lcode +".rsc";
            this.langCode = lcode;
            PrepaireKeyboardFile(filepath);
        }

        private void effectsEnableCB_CheckedChanged(object sender, EventArgs e)
        {
            effectsSelectButton.Enabled = !effectsSelectButton.Enabled;
            if (effectsEnableCB.Checked)
                MessageBox.Show("Выберите папку с эффектами.");
            else if (!string.IsNullOrEmpty(effectsFolderPath))
            {
                fwSize -= (((double)DirSize(new DirectoryInfo(effectsFolderPath))) / 1024) / 1024;
                fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
                effectsFolderPath = string.Empty;
            }
        }

        private void fontsCB_CheckedChanged(object sender, EventArgs e)
        {
            fontSelectButton.Enabled = !fontSelectButton.Enabled;
            if (fontsCB.Checked)
                MessageBox.Show("Выберите папку с шрифтами. Имена шрифтов должны быть такими: s60snr.ttf, s60ssb.ttf, s60tsb.ttf, s60zdigi.ttf!");
            else if(!string.IsNullOrEmpty(fontFolderPath))
            {
                fwSize -= (((double)DirSize(new DirectoryInfo(fontFolderPath))) / 1024) / 1024;
                fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
                fontFolderPath = string.Empty;
            }
        }

        private void CopyOwnFiles()
        {
            if (Directory.Exists(yourFilesPath))
            {
                string[] files = Directory.GetFiles(yourFilesPath, "*.*", SearchOption.AllDirectories);
                string filename, dir;
                string[] sep = new string[] { "YourFiles" };
                foreach (string s in files)
                {
                    filename = s.Split(sep, StringSplitOptions.RemoveEmptyEntries)[1];
                    dir = filename.Substring(0, filename.LastIndexOf('\\') + 1);
                    if (!Directory.Exists(firmwarePath + dir))
                        Directory.CreateDirectory(firmwarePath + dir);
                    File.Copy(s, firmwarePath + filename, true);
                }
            }
            else
            {
                log.AddError("Отсутствует файл: " + yourFilesPath, new FileNotFoundException("File not found!", yourFilesPath));
            }
        }

        private string ParseVersion()
        {
            string version = Assembly.GetExecutingAssembly().GetName().Version.ToString();
            string[] elements = version.Split('.');
            return string.Format("{0}.{1} build {2}", elements[0], elements[1], elements[2]);
        }

        private void cookToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DateTime startTime = DateTime.Now;
            writer = new StreamWriter(Application.StartupPath + "\\changes.txt");
            writer.WriteLine("\\* Данная прошивка модифицирована при помощи программы Nokia Firmware Cooker {0} *\\", ParseVersion());
            writer.WriteLine("\\* Автор программы Dedushk@. Обсуждение здесь - http://forum.allnokia.ru/viewtopic.php?t=64667 *\\");
            writer.WriteLine(string.Empty);
            #region Main Tab
            currentOperationText.Text = "Текущая операция: Применяю основные настройки";
            if (fullCB.Checked)
            {
                AddRomPatcherPlus();
                ++changesCount;
                if (!fullInstallserverCB.Checked)
                    writer.WriteLine("{0}. Вшит RomPatcher+ с патчами (Open4All, InstallServer)", changesCount);
                else
                    writer.WriteLine("{0}. Вшит RomPatcher+ с патчем Open4All", changesCount);
            }
            del();
            if (fullInstallserverCB.Checked)
            {
                CopyFile("installserver.exe", "\\sys\\bin\\installserver.exe");
                ++changesCount;
                writer.WriteLine("{0}. Вшит патченный installserver для установки неподписанных приложений", changesCount);
            }
            del();
            if (sisCapsCB.Checked)
            {
                CopyFile("swipolicy.ini", swipolicyPath);
                WriteDataValueToConfigFile("101FD64E.txt", "0x4", "1");
                ++changesCount;
                writer.WriteLine("{0}. Предоставлены расширенные права для установки SIS", changesCount);
            }
            del();
            if (javaCapsCB.Checked)
            {
                AddJavaCaps();
                ++changesCount;
                writer.WriteLine("{0}. Предоставлены полные права Java-приложениям", changesCount);
            }
            del();
            if (widgCapsCB.Checked)
            {
                WriteDataValueToConfigFile("1028281F.txt", "0x2", "0");
                ++changesCount;
                writer.WriteLine("{0}. Убраны запросы виджетов", changesCount);
            }
            del();
            if (cancelSmsCB.Checked)
            {
                WriteDataValueToConfigFile("200122A4.txt", "0x4", "Language=100;Promo=000;PAplugin=000;Switch=001;Personalisation=001;EmailSettings=000;10281c96;2001FE2F");
                ++changesCount;
                writer.WriteLine("{0}. Убраны приветствие и SMS при первом запуске", changesCount);
            }
            del();
            if (sensorActivateCB.Checked)
            {
                WriteDataValueToConfigFile("10282df0.txt", "0x1", "1");
                WriteDataValueToConfigFile("10282df0.txt", "0x2", "0");
                WriteDataValueToConfigFile("10282df0.txt", "0x3", "7");
                WriteDataValueToConfigFile("10282df0.txt", "0x4", "0");
                WriteDataValueToConfigFile("10282df0.txt", "0x100002", "7");
                WriteDataValueToConfigFile("10282df0.txt", "0x100003", "7");
                ++changesCount;
                writer.WriteLine("{0}. Активирован пункт настроек \"Управление касанием\" (по умолчанию все галки в нем сняты)", changesCount);
            }
            del();
            if (hideOviCB.Checked)
            {
                CopyFile("oviimps_pbkkplugin.dll", oviPluginPath);
                ++changesCount;
                writer.WriteLine("{0}. Убраны Контакты OVI", changesCount);
            }
            del();
            if (delDefBookmarksCB.Checked)
            {
                CopyFile("BookmarkImportSample.txt", defBookmarksPath);
                ++changesCount;
                writer.WriteLine("{0}. Удалены стандартные закладки", changesCount);
            }
            del();
            if (decreasePhotoCompressionCB.Checked)
            {
                CopyFile("10282EDC.txt", privateConfigPath + "10282EDC.txt");
                ++changesCount;
                writer.WriteLine("{0}. Уменьшено сжатие фотографий", changesCount);
            }
            del();
            if (enableLandscapeModeCB.Checked)
            {
                CopyFile("200159ED.txt", privateConfigPath + "200159ED.txt");
                ++changesCount;
                writer.WriteLine("{0}. Ландшафтный режим везде включен", changesCount);
            }
            del();
            if (moveBrowserCacheToFlashCB.Checked)
            {
                WriteDataValueToConfigFile("101F8557.txt", "0x3", "e:\\\\System\\\\Cache");
                WriteDataValueToConfigFile("101F8557.txt", "0x4", "e:\\\\System\\\\Cache\\\\op");
                WriteDataValueToConfigFile("101F8557.txt", "0x8", "e:\\\\System\\\\Cache\\\\vss");
                string tmp = ReadDataValueFromConfigFile("101F8557.txt", "0xF");
                tmp = tmp.Replace("C;", "E;");
                WriteDataValueToConfigFile("101F8557.txt", "0xF", tmp);
                ++changesCount;
                writer.WriteLine("{0}. Кэш браузера перенесен на флешку", changesCount);
            }
            del();
            if (enableHsToolbarCB.Checked)
            {
                WriteDataValueToConfigFile("10275102.txt", "0x700", "1");
                ++changesCount;
                writer.WriteLine("{0}. Тулбар из 3-ех иконок на столе включен", changesCount);
            }
            del();
            if (sisTransferProtectionCB.Checked)
            {
                CopyFile("ClosedContentList.rsc", "\\resource\\ClosedContentList.rsc");
                ++changesCount;
                writer.WriteLine("{0}. Запрет на передачу SIS через стандартный файлменеджер снят", changesCount);
            }
            del();
            if (rotateOptionCB.Checked)
            {
                WriteDataValueToConfigFile("10008d39.txt", "0x44", "1");
                ++changesCount;
                writer.WriteLine("{0}. Опция \"Поворот\" экрана в браузере включена", changesCount);
            }
            del();
            if (addAutoInstCB.Checked)
            {
                AddAutoInstaller();
                ++changesCount;
                writer.WriteLine("{0}. Вшит AutoInstaller", changesCount);
            }
            del();
            if (disableLightAndVibraCB.Checked)
            {
                if (!Directory.Exists(firmwarePath + "\\private\\10282BC4\\Rules\\"))
                    Directory.CreateDirectory(firmwarePath + "\\private\\10282BC4\\Rules\\");
                CopyFile("TubeActivityActions.rul", "\\private\\10282BC4\\Rules\\TubeActivityActions.rul");
                CopyFile("TubeActivityActions.rul", "\\private\\10282BC4\\Rules\\TubeDevLock.rul");
                ++changesCount;
                writer.WriteLine("{0}. Отключена подсветка клавиш и вибрация при блокировке", changesCount);
            }
            del();
            if (disableDrmCB.Checked)
            {
                WriteDataValueToConfigFile("101F880D.txt", "0x2", "0");
                ++changesCount;
                writer.WriteLine("{0}. Отключена DRM-защита", changesCount);
            }
            del();
            if (disableChargerNoteCB.Checked)
            {
                WriteDataValueToConfigFile("101F8769.txt", "0x3", "0");
                ++changesCount;
                writer.WriteLine("{0}. Отключены уведомления о зарядке", changesCount);
            }
            del();
            if (enableResumeDownloadsCB.Checked)
            {
                WriteDataValueToConfigFile("101F861B.txt", "0x5", "1");
                ++changesCount;
                writer.WriteLine("{0}. Включена докачка оборванных загрузок в браузере", changesCount);
            }
            del();
            if (disableEffectsCB.Checked)
            {
                WriteDataValueToConfigFile("102818E8.txt", "0x9", "0x7fffffff");
                ++changesCount;
                writer.WriteLine("{0}. Эффекты тем по умолчанию отключены", changesCount);
            }
            del();
            if (opLogoOptionActivateCB.Checked)
            {
                WriteDataValueToConfigFile("101F877C.txt", "0x4", "1");
                ++changesCount;
                writer.WriteLine("{0} Активирован пункт \"Логотип оператора\" в настройках главного экрана", changesCount);
            }
            del();
            if (disablePereadresNoteCB.Checked)
            {
                CopyFile(currentProfile.phoneUi, "\\resource\\apps\\phoneui.r16");
                ++changesCount;
                writer.WriteLine("{0} Убрано сообщение \"Внимание! Включена переадресация\"", changesCount);
            }
            del();
            #endregion

            #region Settings Tab
            currentOperationText.Text = "Текущая операция: Применяю дополнительные настройки";
            if (!config.Modifed(defBTNameText))
            {
                WriteDefaultBluetoothName();
                ++changesCount;
                writer.WriteLine("{0}. Изменено имя BT по умолчанию на {1}", changesCount, defBTNameText.Text);
            }
            del();
            if (!config.Modifed(defSavePathBtText))
            {
                WriteDataValueToConfigFile("10204DAB.txt", "0xA", defSavePathBtText.Text);
                ++changesCount;
                writer.WriteLine("{0}. Изменен путь сохранения файлов по BT на {1}", changesCount, defSavePathBtText.Text);
            }
            del();
            if (!config.Modifed(defThemeUidText))
            {
                WriteDataValueToConfigFile("101F876F.txt", "0x14", defThemeUidText.Text);
                ++changesCount;
                writer.WriteLine("{0}. Вшита своя стандартная тема", changesCount);
            }
            del();
            if (!config.Modifed(fotaReservSizeNUD))
            {
                WriteDataValueToConfigFile("102072c6.txt", "0x1", fotaReservSizeNUD.Value.ToString());
                ++changesCount;
                writer.WriteLine("{0}. Изменен размер резерва под FOTA на {1} МБ", changesCount, Math.Round((fotaReservSizeNUD.Value / 1024) / 1024, 1));
            }
            del();
            if (!config.Modifed(webSuffixListText))
            {
                WriteDataValueToConfigFile("10008d39.txt", "0x54", webSuffixListText.Text);
                ++changesCount;
                writer.WriteLine("{0}. Добавлены суффиксы адресов в браузере", changesCount);
            }
            del();
            if (!config.Modifed(brightLevelNUD))
            {
                WriteDataValueToConfigFile("10200C8C.txt", "0x2", brightLevelNUD.Value.ToString());
                ++changesCount;
                writer.WriteLine("{0}. Изменен уровень яркости по умолчанию на {1}", changesCount, brightLevelNUD.Value);
            }
            del();
            if (!config.Modifed(lightTimeoutNUD))
            {
                WriteDataValueToConfigFile("10200C8C.txt", "0x6", lightTimeoutNUD.Value.ToString());
                ++changesCount;
                writer.WriteLine("{0}. Изменен таймаут подсветки на {1} сек.", changesCount, lightTimeoutNUD.Value);
            }
            del();
            if (!config.Modifed(alarmPeriodNUD))
            {
                WriteDataValueToConfigFile("101f874d.txt", "0x2", alarmPeriodNUD.Value.ToString());
                ++changesCount;
                writer.WriteLine("{0}. Изменен период звонка будильника на {1} мин.", changesCount, alarmPeriodNUD.Value);
            }
            del();
            CopyFontsEffectsAndPatches();
            del();
            if (disableRemoteSimAccessCB.Checked)
            {
                WriteDataValueToConfigFile("10204DAC.txt", "0x3", "0");
                ++changesCount;
                writer.WriteLine("{0}. {1} удаленный доступ к SIM", changesCount, ConvertBoolToString(!disableRemoteSimAccessCB.Checked));
            }
            del();
            if (enableSpeedDialCB.Checked)
            {
                WriteDataValueToConfigFile("101F877E.txt", "0x3", "1");
                ++changesCount;
                writer.WriteLine("{0}. {1} быстрый набор", changesCount, ConvertBoolToString(enableSpeedDialCB.Checked));
            }
            del();
            if (showCallDurationCB.Checked)
            {
                WriteDataValueToConfigFile("101F874E.txt", "0x9", "1");
                ++changesCount;
                writer.WriteLine("{0}. {1}о отображение информации после звонка", changesCount, ConvertBoolToString(showCallDurationCB.Checked));
            }
            del();
            if (!config.Modifed(flashCardNameText))
            {
                WriteDataValueToConfigFile("1020506B.txt", "0x9", flashCardNameText.Text);
                ++changesCount;
                writer.WriteLine("{0}. Изменено имя флешки по умолчанию на {1}", changesCount, flashCardNameText.Text);
            }
            del();
            if (!config.Modifed(zeroButtonAppText))
            {
                WriteDataValueToConfigFile("102828b2.txt", "0x3", zeroButtonAppText.Text);
                ++changesCount;
                writer.WriteLine("{0}. Изменено приложение на клавише \"0\" на приложение с UID: {1}", changesCount, zeroButtonAppText.Text);
            }
            del();
            if (enableFlashCardIndicatorCB.Checked)
            {
                WriteDataValueToConfigFile("101f8764.txt", "0x8", "1");
                ++changesCount;
                writer.WriteLine("{0}. Включено отображение значка флеш-карты", changesCount);
            }
            del();
            if (removeDefaultGamesCB.Checked)
            {
                CopyDir(new DirectoryInfo(Application.StartupPath + "\\Resources\\RemoveGames\\"), "RemoveGames");
                ++changesCount;
                writer.WriteLine("{0}. Удалены стандартные игры", changesCount);
            }
            del();
            if (!disableUsbNoticeCB.Checked)
            {
                WriteDataValueToConfigFile("101f8801.txt", "0x1", "0");
                ++changesCount;
                writer.WriteLine("{0}. Отключены запросы при подключении к USB", changesCount);
            }
            del();
            if (usbTypeCombo.SelectedIndex != 0)
            {
                if (usbTypeCombo.SelectedIndex == 1)
                    WriteDataValueToConfigFile("101f8801.txt", "0x2", "2");
                else if (usbTypeCombo.SelectedIndex == 2)
                    WriteDataValueToConfigFile("101f8801.txt", "0x2", "3");
                else if (usbTypeCombo.SelectedIndex == 3)
                    WriteDataValueToConfigFile("101f8801.txt", "0x2", "4");
                ++changesCount;
                writer.WriteLine("{0}. Тип USB по умолчанию изменен на \"{1}\"", changesCount, deliverPeriodCombo.Items[deliverPeriodCombo.SelectedIndex]);
            }
            del();
            if (accTypeCombo.SelectedIndex != 0)
            {
                if (accTypeCombo.SelectedIndex == 1)
                    WriteDataValueToConfigFile("1020505A.txt", "0x1", "8");
                ++changesCount;
                writer.WriteLine("{0}. Тип аксессуара по умолчанию изменен на наушники", changesCount);
            }
            del();
            if (removeCameraSoundsCB.Checked)
            {
                CopyDir(new DirectoryInfo(Application.StartupPath + "\\Resources\\NoCameraSounds\\"), "NoCameraSounds");
                ++changesCount;
                writer.WriteLine("{0}. Убраны звуки фокусировки и съемки камеры", changesCount);
            }
            del();
            if (disableDataConfigurationCB.Checked)
            {
                WriteDataValueToConfigFile("101F8763.txt", "0xa", "0");
                ++changesCount;
                writer.WriteLine("{0}. Отключена настройка даты и времени при первом запуске", changesCount);
            }
            del();
            #endregion

            #region Message Settings
            currentOperationText.Text = "Текущая операция: Применяю настройки сообщений";
            if (!config.Modifed(savedMessagesCountNUD))
            {
                WriteDataValueToConfigFile("101f87eb.txt", "0x1", savedMessagesCountNUD.Value.ToString());
                ++changesCount;
                writer.WriteLine("{0}. Количество сохраняемых сообщений - {1}", changesCount, savedMessagesCountNUD.Value);
            }
            del();
            if (!config.Modifed(messageMemoryCombo))
            {
                if (messageMemoryCombo.SelectedIndex == 0)
                {
                    WriteDataValueToConfigFile("101f87eb.txt", "0x3", "2");
                    ++changesCount;
                    writer.WriteLine("{0}. Память хранения сообщений по умолчанию изменена на C", changesCount);
                }
                else if (messageMemoryCombo.SelectedIndex == 1)
                {
                    WriteDataValueToConfigFile("101f87eb.txt", "0x3", "4");
                    ++changesCount;
                    writer.WriteLine("{0}. Память хранения сообщений по умолчанию изменена на E", changesCount);
                }
            }
            del();
            if (!config.Modifed(deliverPeriodCombo))
            {
                if (deliverPeriodCombo.SelectedIndex == 0)
                    WriteDataValueToConfigFile("101f87ef.txt", "0x7", "60");
                else if (deliverPeriodCombo.SelectedIndex == 1)
                    WriteDataValueToConfigFile("101f87ef.txt", "0x7", "360");
                else if (deliverPeriodCombo.SelectedIndex == 2)
                    WriteDataValueToConfigFile("101f87ef.txt", "0x7", "1440");
                else if (deliverPeriodCombo.SelectedIndex == 3)
                    WriteDataValueToConfigFile("101f87ef.txt", "0x7", "4320");
                else if (deliverPeriodCombo.SelectedIndex == 4)
                    WriteDataValueToConfigFile("101f87ef.txt", "0x7", "10080");
                else if (deliverPeriodCombo.SelectedIndex == 5)
                    WriteDataValueToConfigFile("101f87ef.txt", "0x7", "635040");
                ++changesCount;
                writer.WriteLine("{0}. Период доставки сообщений по умолчанию изменен на {1}", changesCount, deliverPeriodCombo.Items[deliverPeriodCombo.SelectedIndex]);
            }
            del();
            if (!config.Modifed(deliveryReportCB))
            {
                if (deliveryReportCB.Checked)
                    WriteDataValueToConfigFile("101f87ef.txt", "0x1", "1");
                else
                    WriteDataValueToConfigFile("101f87ef.txt", "0x1", "0");
                ++changesCount;
                writer.WriteLine("{0}. Отчет о доставке по умолчанию {1}", changesCount, ConvertBoolToString(deliveryReportCB.Checked));
            }
            del();
            if (!config.Modifed(sameCenterAnswerCB))
            {
                if (sameCenterAnswerCB.Checked)
                    WriteDataValueToConfigFile("101f87ef.txt", "0x4", "1");
                else
                    WriteDataValueToConfigFile("101f87ef.txt", "0x4", "0");
                ++changesCount;
                writer.WriteLine("{0}. Ответ через тот же центр по умолчанию {1}", changesCount, ConvertBoolToString(sameCenterAnswerCB.Checked));
            }
            del();
            if (!config.Modifed(symbolCodingCB))
            {
                if (symbolCodingCB.Checked)
                    WriteDataValueToConfigFile("101f87ef.txt", "0x8", "1");
                else
                    WriteDataValueToConfigFile("101f87ef.txt", "0x8", "0");
            }
            del();
            if (!config.Modifed(messageMenuItemCList))
            {
                if (messageMenuItemCList.GetItemChecked(0))
                    WriteDataValueToConfigFile("101f87eb.txt", "0xC", "5");
                else
                    WriteDataValueToConfigFile("101f87eb.txt", "0xC", "-1");
                if (messageMenuItemCList.GetItemChecked(1))
                    WriteDataValueToConfigFile("101f87eb.txt", "0xD", "4098");
                else
                    WriteDataValueToConfigFile("101f87eb.txt", "0xD", "-1");
                if (messageMenuItemCList.GetItemChecked(2))
                    WriteDataValueToConfigFile("101f87eb.txt", "0xE", "7");
                else
                    WriteDataValueToConfigFile("101f87eb.txt", "0xE", "-1");
                if (messageMenuItemCList.GetItemChecked(3))
                    WriteDataValueToConfigFile("101f87eb.txt", "0xF", "4101");
                else
                    WriteDataValueToConfigFile("101f87eb.txt", "0xF", "-1");
                if (messageMenuItemCList.GetItemChecked(4))
                    WriteDataValueToConfigFile("101f87eb.txt", "0x10", "4100");
                else
                    WriteDataValueToConfigFile("101f87eb.txt", "0x10", "-1");
                if (messageMenuItemCList.GetItemChecked(5))
                    WriteDataValueToConfigFile("101f87eb.txt", "0x11", "4099");
                else
                    WriteDataValueToConfigFile("101f87eb.txt", "0x11", "-1");
                if (messageMenuItemCList.GetItemChecked(6))
                    WriteDataValueToConfigFile("101f87eb.txt", "0x12", "6");
                else
                    WriteDataValueToConfigFile("101f87eb.txt", "0x12", "-1");
                if (messageMenuItemCList.GetItemChecked(7))
                    WriteDataValueToConfigFile("101f87eb.txt", "0x13", "4104");
                else
                    WriteDataValueToConfigFile("101f87eb.txt", "0x13", "-1");
                ++changesCount;
                writer.WriteLine("{0}. Изменено меню Сообщения", changesCount);
            }
            del();
            if (indicationPeriodNUD.Value != 60M)
            {
                WriteDataValueToConfigFile("2000E54D.txt", "0x1", indicationPeriodNUD.Value.ToString());
                ++changesCount;
                writer.WriteLine("{0}. Изменено время мерцания светового индикатора на {1}", changesCount, indicationPeriodNUD.Value);
            }
            del();
            #endregion

            #region Dictophone Settings
            currentOperationText.Text = "Текущая операция: Применяю настройки диктафона";
            if (!config.Modifed(callRecordCB))
            {
                if (callRecordCB.Checked)
                {
                    WriteDataValueToConfigFile("101F87A3.txt", "0x0", "1");
                    ++changesCount;
                    writer.WriteLine("{0}. {1}а запись разговоров", changesCount, ConvertBoolToString(callRecordCB.Checked));
                }
            }
            del();
            if (!config.Modifed(audioFormat))
            {
                if (audioFormat.SelectedIndex == 0)
                    WriteDataValueToConfigFile("101F87A3.txt", "0x1", "0");
                else if (audioFormat.SelectedIndex == 1)
                    WriteDataValueToConfigFile("101F87A3.txt", "0x1", "1");
                else if (audioFormat.SelectedIndex == 2)
                    WriteDataValueToConfigFile("101F87A3.txt", "0x1", "2");
                ++changesCount;
                writer.WriteLine("{0}. Формат записи диктофона изменен на {1}", changesCount, audioFormat.Items[audioFormat.SelectedIndex]);
            }
            del();
            if (!config.Modifed(audioQuality))
            {
                if (audioQuality.SelectedIndex == 0)
                    WriteDataValueToConfigFile("101F87A3.txt", "0x6", "0");
                else if (audioQuality.SelectedIndex == 1)
                    WriteDataValueToConfigFile("101F87A3.txt", "0x6", "1");
                else if (audioQuality.SelectedIndex == 2)
                    WriteDataValueToConfigFile("101F87A3.txt", "0x6", "2");
                ++changesCount;
                writer.WriteLine("{0}. Качество записи диктафона изменено на {1}", changesCount, audioQuality.Items[audioQuality.SelectedIndex]);
            }
            del();
            if (!config.Modifed(recordDurationNUD))
            {
                WriteDataValueToConfigFile("101F87A3.txt", "0x7", recordDurationNUD.Value.ToString());
                ++changesCount;
                writer.WriteLine("{0}. Маскимальная длительность записи изменена на {1}", changesCount, recordDurationNUD.Value);
            }
            del();
            foreach (RadioButton r in amr)
            {
                if (!config.Modifed(r))
                {
                    if (r.Checked)
                    {
                        WriteDataValueToConfigFile("101F87A3.txt", "0x10", r.Text);
                        ++changesCount;
                        writer.WriteLine("{0}. Битрейт AMR в диктафоне изменен на {1}", changesCount, r.Text);
                    }
                }
            }
            del();
            if (!config.Modifed(aacBitrateNUD))
            {
                WriteDataValueToConfigFile("101F87A3.txt", "0x11", aacBitrateNUD.Value.ToString());
                ++changesCount;
                writer.WriteLine("{0}. Битерйт AAC в диктафоне изменен на {1}", changesCount, aacBitrateNUD.Value);
            }
            del();
            if (!config.Modifed(aacSamplerateNUD))
            {
                WriteDataValueToConfigFile("101F87A3.txt", "0x12", aacSamplerateNUD.Value.ToString());
                ++changesCount;
                writer.WriteLine("{0}. Частота дискретизации AAC изменена на {1}", changesCount, aacSamplerateNUD.Value);
            }
            del();
            if (!config.Modifed(monoStereo))
            {
                if (monoStereo.SelectedIndex == 0)
                    WriteDataValueToConfigFile("101F87A3.txt", "0x13", "1");
                else if (monoStereo.SelectedIndex == 1)
                    WriteDataValueToConfigFile("101F87A3.txt", "0x13", "2");
                ++changesCount;
                writer.WriteLine("{0}. Количество каналов записи изменено на {1}", changesCount, monoStereo.Items[monoStereo.SelectedIndex]);
            }
            del();
            if (!config.Modifed(aacRecordDurationNUD))
            {
                WriteDataValueToConfigFile("101F87A3.txt", "0x14", aacRecordDurationNUD.Value.ToString());
                ++changesCount;
                writer.WriteLine("{0}. Максимальная длительность записи AAC изменена на {1}", changesCount, aacRecordDurationNUD.Value);
            }
            del();
            #endregion

            #region Kinetic Settings
            currentOperationText.Text = "Текущая операция: Применяю настройки кинетической прокрутки";
            bool edit = false;
            if (!config.Modifed(kinetic1))
            {
                WriteDataValueToConfigFile("20021192.txt", "0x1", kinetic1.Value.ToString());
                edit = true;
            }
            if (!config.Modifed(kinetic2))
            {
                WriteDataValueToConfigFile("20021192.txt", "0x2", kinetic2.Value.ToString());
                edit = true;
            }
            if (!config.Modifed(kinetic3))
            {
                WriteDataValueToConfigFile("20021192.txt", "0x3", kinetic3.Value.ToString());
                edit = true;
            }
            if (!config.Modifed(kinetic4))
            {
                WriteDataValueToConfigFile("20021192.txt", "0x4", kinetic4.Value.ToString());
                edit = true;
            }
            if (!config.Modifed(kinetic5))
            {
                WriteDataValueToConfigFile("20021192.txt", "0x5", kinetic5.Value.ToString());
                edit = true;
            }
            if (!config.Modifed(kinetic6))
            {
                WriteDataValueToConfigFile("20021192.txt", "0x6", kinetic6.Value.ToString());
                edit = true;
            }
            if (!config.Modifed(kinetic7))
            {
                WriteDataValueToConfigFile("20021192.txt", "0x8", kinetic7.Value.ToString());
                edit = true;
            }
            if (!config.Modifed(kinetic8))
            {
                WriteDataValueToConfigFile("20021192.txt", "0xB", kinetic8.Value.ToString());
                edit = true;
            }
            if (edit)
            {
                ++changesCount;
                writer.WriteLine("{0}. Отредактирована кинетика", changesCount);
            }
            del();
            if (disableKineticCB.Checked)
            {
                WriteDataValueToConfigFile("20021192.txt", "0x9", "0");
                ++changesCount;
                writer.WriteLine("{0}. Отключена кинетика везде", changesCount);
            }
            del();
            if (killMenuKineticCB.Checked)
            {
                CopyDir(new DirectoryInfo(Application.StartupPath + "\\Resources\\KillMenuKinetic\\"), "KillMenuKinetic");
                ++changesCount;
                writer.WriteLine("{0}. Отключена кинетика в меню", changesCount);
            }
            del();
            #endregion

            #region Perfomance Settings
            currentOperationText.Text = "Текущая операция: Применяю настройки производительности";
            if (increaseSysCacheCB.Checked)
            {
                if (!Directory.Exists(firmwarePath + "\\sys\\data\\"))
                    Directory.CreateDirectory(firmwarePath + "\\sys\\data\\");
                CopyFile("ESTARTCOMP.TXT", "\\sys\\data\\ESTARTCOMP.TXT");
                CopyFile("ESTARTTEXTSHELL.TXT", "\\sys\\data\\ESTARTTEXTSHELL.TXT");
                CopyFile("estartmagic.TXT", "\\sys\\data\\estartmagic.TXT");
                ++changesCount;
                writer.WriteLine("{0}. Увеличен кэш дисков", changesCount);
            }
            del();
            if (cameraCacheDisableCB.Checked)
            {
                WriteDataValueToConfigFile("10208A43.txt", "0x2", "0");
                ++changesCount;
                writer.WriteLine("{0}. Кэширование Камеры отключено", changesCount);
            }
            del();
            if (!config.Modifed(heapSizeNUD) || !config.Modifed(appDelayNUD))
            {
                WriteHeapAndDelayData();
                ++changesCount;
                writer.WriteLine("{0}. Изменен размер HEAP на {1} байт", changesCount, heapSizeNUD.Value);
                ++changesCount;
                writer.WriteLine("{0}. Изменено время задержки приложений на {1} мкс", changesCount, appDelayNUD.Value);
            }
            del();
            if (!config.Modifed(fpsNUD))
            {
                WriteDataValueToConfigFile("10283344.txt", "0x0", fpsNUD.Value.ToString());
                ++changesCount;
                writer.WriteLine("{0}. Изменено FPS приложений на {1}", changesCount, fpsNUD.Value);
            }
            del();
            if (!config.Modifed(cpuTimeNUD))
            {
                WriteDataValueToConfigFile("10283344.txt", "0x1", cpuTimeNUD.Value.ToString());
                ++changesCount;
                writer.WriteLine("{0}. Изменен процент процессорного времени для alfappserver.exe на {1}%", changesCount, cpuTimeNUD.Value);
            }
            del();
            if (!config.Modifed(maxResourceCacheNUD))
            {
                WriteDataValueToConfigFile("10283344.txt", "0x3", maxResourceCacheNUD.Value.ToString());
                ++changesCount;
                writer.WriteLine("{0}. Кэш ресурсов изменен - {1} КБ", changesCount, maxResourceCacheNUD.Value);
            }
            del();
            if (!config.Modifed(graphicEffectsComplexiyNUD))
            {
                WriteDataValueToConfigFile("10283344.txt", "0x4", graphicEffectsComplexiyNUD.Value.ToString());
                ++changesCount;
                writer.WriteLine("{0}. Сложность эффектов изменена  на {1}", changesCount, graphicEffectsComplexiyNUD.Value);
            }
            del();
            if (!config.Modifed(maxCacheableItemsNUD))
            {
                WriteDataValueToConfigFile("101F9775.txt", "0x3", maxCacheableItemsNUD.Value.ToString());
                ++changesCount;
                writer.WriteLine("{0}. Максимальное число кэшируемых объектов изменено на {1}", changesCount, maxCacheableItemsNUD.Value);
            }
            del();
            if (!config.Modifed(maxSysCacheSizeNUD))
            {
                WriteDataValueToConfigFile("101F9775.txt", "0x4", maxSysCacheSizeNUD.Value.ToString());
                ++changesCount;
                writer.WriteLine("{0}. Максимальный размер системного кэша изменен на {1} байт", changesCount, maxSysCacheSizeNUD.Value);
            }
            del();
            if (!config.Modifed(cacheToERadio))
            {
                if (cacheToERadio.Checked)
                    WriteDataValueToConfigFile("101F9775.txt", "0x1", "E:");
                else
                {
                    WriteDataValueToConfigFile("101F9775.txt", "0x1", "C:");
                    ++changesCount;
                    writer.WriteLine("{0}. Системный кэш перенесен на флешку", changesCount);
                }
            }
            del();
            if (clearAutorunCB.Checked)
            {
                CopyDir(new DirectoryInfo(Application.StartupPath + "\\Resources\\" + currentProfile.autorun), "Autorun");
                ++changesCount;
                writer.WriteLine("{0}. Из автозагрузки убраны лишние программы", changesCount);
            }
            del();
            if (bufferPercentNUD.Value != 35M)
            {
                WriteDataValueToConfigFile("10207B74.txt", "0x5", bufferPercentNUD.Value.ToString());
                ++changesCount;
                writer.WriteLine("{0}. Процент буферизации видео изменен на {1}", changesCount, bufferPercentNUD.Value);
            }
            del();
            #endregion

            #region Player\Gallery Settings
            /*currentOperationText.Text = "Текущая операция: Применяю настройки автозапуска";
            if (autorunEnableCB.Checked)
            {
                WriteAutorunList();
                ++changesCount;
                writer.WriteLine("{0}. Отредактирована автозагрузка", changesCount);
            }
            del();*/

            currentOperationText.Text = "Текущая операция: Применяю настройки плеера и галереи";
            if (!config.Modifed(playerScanList) || !config.Modifed(galleryScanClist) || !config.Modifed(galleryScanElist) || !config.Modifed(hideAppUidList))
                WritePlayerGalleryAndMenuSettings();
            del();
            if (playerVolumeSlider.Value != 40)
            {
                WriteDataValueToConfigFile("101ffc03.txt", "0x1", playerVolumeSlider.Value.ToString());
                ++changesCount;
                writer.WriteLine("{0}. Громкость плеера по умолчанию изменена на {1}", changesCount, playerVolumeSlider.Value);
            }
            del();
            #endregion

            #region Design Settings
            currentOperationText.Text = "Текущая операция: Применяю настройки украшательств";
            if (startupSoundCB.Checked)
            {
                if (!string.IsNullOrEmpty(startupSoundPath))
                {
                    string ext = startupSoundPath.Substring(startupSoundPath.LastIndexOf('.') + 1);
                    if (ext.Equals("aac"))
                        File.Copy(startupSoundPath, firmwarePath + "\\data\\Startup_tone.aac");
                    else if (ext.Equals("mp3"))
                    {
                        WriteDataValueToConfigFile("101F8763.txt", "0x3", "z:\\data\\Startup_tone.mp3");
                        File.Copy(startupSoundPath, firmwarePath + "\\data\\Startup_tone.mp3");
                    }
                    ++changesCount;
                    writer.WriteLine("{0}. Мелодия включения изменена", changesCount);
                }
            }
            del();
            if (startupSplashCB.Checked)
            {
                if (!string.IsNullOrEmpty(startupSplashPath))
                {
                    File.Copy(startupSplashPath, firmwarePath + "\\resource\\apps\\SplashScreen.mif");
                    ++changesCount;
                    writer.WriteLine("{0}. Заставка включения заменена", changesCount);
                }
            }
            del();
            if (shutdownSplashCB.Checked)
            {
                if (!string.IsNullOrEmpty(shutdownSplashPath))
                {
                    File.Copy(shutdownSplashPath, firmwarePath + "\\resource\\apps\\SysAp.mif");
                    ++changesCount;
                    writer.WriteLine("{0}. Заставка выключения заменена", changesCount);
                }
            }
            del();
            if (selectOwnMenuFileCB.Checked)
            {
                if (!string.IsNullOrEmpty(menuFilePath))
                {
                    File.Copy(menuFilePath, firmwarePath + "\\private\\101F4CD2\\appshelldata.xml");
                    ++changesCount;
                    writer.WriteLine("{0}. Изменена структура меню", changesCount);
                }
            }
            del();
            if (vodafoneCB.Checked)
            {
                CopyDir(new DirectoryInfo(Application.StartupPath + "\\Resources\\Vodafone\\"), "Vodafone");
                WriteDataValueToConfigFile("10275102.txt", "0x101", "0");
                WriteDataValueToConfigFile("10275102.txt", "0x100", "271012084");
                ++changesCount;
                writer.WriteLine("{0}. Вшит стол Vodafone", changesCount);
            }
            del();
            if (tornadoCB.Checked)
            {
                CopyDir(new DirectoryInfo(Application.StartupPath + "\\Resources\\Tornado\\"), "Tornado");
                WriteDataValueToConfigFile("10275102.txt", "0x101", "0");
                WriteDataValueToConfigFile("10275102.txt", "0x100", "271012084");
                WriteDataValueToConfigFile("101F877C.txt", "0xc", "536968409");
                ++changesCount;
                writer.WriteLine("{0}. Вшит стол Tornado", changesCount);
            }
            del();
            if (tsunamiCB.Checked)
            {
                CopyDir(new DirectoryInfo(Application.StartupPath + "\\Resources\\Tsunami\\"), "Tsunami");
                ++changesCount;
                writer.WriteLine("{0}. Вшит стол Tsunami", changesCount);
            }
            del();
            if (startupSoundVolumeSlider.Value != 4)
            {
                WriteDataValueToConfigFile("101F8763.txt", "0x2", startupSoundVolumeSlider.Value.ToString());
                ++changesCount;
                writer.WriteLine("{0}. Громкость мелодии включения изменена на {1}", changesCount, startupSoundVolumeSlider.Value.ToString());
            }
            del();
            if (!config.Modifed(homeScreensDefaultCombo))
            {
                switch (homeScreensDefaultCombo.SelectedItem.ToString())
                {
                    case "Стандартный":
                        WriteDataValueToConfigFile("10207342.txt", "0x102750f0", "271063148");
                        break;
                    case "Панель контактов":
                        WriteDataValueToConfigFile("10207342.txt", "0x102750f0", "536988645");
                        break;
                    case "Панель ссылок":
                        WriteDataValueToConfigFile("10207342.txt", "0x102750f0", "271068379");
                        break;
                    case "Панель навигации":
                        WriteDataValueToConfigFile("10207342.txt", "0x102750f0", "271063149");
                        break;
                    case "Полная страница":
                        WriteDataValueToConfigFile("10207342.txt", "0x102750f0", "271063147");
                        break;
                    case "Vodafone":
                        WriteDataValueToConfigFile("10207467.txt", "0x3", "536887713");
                        break;
                    case "Orange Tornado":
                        WriteDataValueToConfigFile("10207467.txt", "0x3", "536968409");
                        break;
                    case "Orange Tsunami":
                        WriteDataValueToConfigFile("10207467.txt", "0x3", "537013223");
                        break;
                }
                ++changesCount;
                writer.WriteLine("{0}. Рабочий стол по умолчанию изменен на {1}", changesCount, homeScreensDefaultCombo.SelectedItem.ToString());
            }
            #endregion

            #region Soft Settings
            if (softList.Items.Count > 0)
            {
                currentOperationText.Text = "Текущая операция: Вшиваю софт";
                DirectoryInfo temp = new DirectoryInfo(Application.StartupPath + "\\temp\\");
                DirectoryInfo[] dirs = temp.GetDirectories();
                foreach (DirectoryInfo dir in dirs)
                    CopyDir(dir, dir.Name);
                foreach (object o in softList.Items)
                {
                    ++changesCount;
                    writer.WriteLine("{0}. Вшита программа {1}", changesCount, o.ToString());
                }
                del();
            }
            #endregion

            #region Keyboard Settings
            currentOperationText.Text = "Текущая операция: Копирую файлы клавиатур";
            if (Directory.Exists(Application.StartupPath + "\\temp\\keys\\"))
            {
                DirectoryInfo di = new DirectoryInfo(Application.StartupPath + "\\temp\\keys\\");
                if (di.GetFiles("peninputvkbwindowconfiginfo_*.rsc", SearchOption.AllDirectories).Length > 0)
                {
                    CopyDir(di, "keys", firmwarePath + "\\resource\\plugins\\");
                    List<string> codes = new List<string>();
                    foreach (FileInfo f in di.GetFiles("peninputvkbwindowconfiginfo_*.rsc", SearchOption.AllDirectories))
                        codes.Add(f.Name.Substring(28, f.Name.IndexOf('.') - 28));
                    string langs = string.Empty;
                    foreach (string s in codes)
                        langs += CodeToLang[s] + ", ";
                    langs = langs.Substring(0, langs.Length - 2);
                    ++changesCount;
                    writer.WriteLine("{0}. Заменены иероглифы для следующих языков(-а): {1}", changesCount, langs);
                }
            }
            del();
            #endregion

            currentOperationText.Text = "Текущая операция: Пишу ScriptInit";
            if (!config.Modifed(scriptInitList))
            {
                WriteScriptInit();
                ++changesCount;
                writer.WriteLine("{0}. Модифицирован ScriptInit", changesCount);
            }
            del();

            currentOperationText.Text = "Текущая операция: Копирую свои файлы..";
            if (copyOwnFilesCB.Checked)
                CopyOwnFiles();
            del();

            #region Language Tab
            currentOperationText.Text = "Текущая операция: Удаляю языки..";
            try
            {
                if (!config.Modifed(defLangCombo) || !config.Modifed(inputLangCList) || !config.Modifed(helpLangCList) || !config.Modifed(phoneLangCList))
                    DeleteLanguageFromFirmware();
            }
            catch (NotSupportedException ex)
            {
                MessageBox.Show("Ошибка! Текскт ошибки: \"" + ex.Message + "\" Соберите прошивку еще раз.");
                progressBar.Value = 0;
                return;
            }
            if (addRusLangCB.Checked)
            {
                CopyDir(new DirectoryInfo(Application.StartupPath + "\\Resources\\" + currentProfile.rus), "rus");
                ++changesCount;
                writer.WriteLine("{0}. Добавлен русский язык ввода", changesCount);
            }
            del();
            if (addUkrLangCB.Checked)
            {
                CopyDir(new DirectoryInfo(Application.StartupPath + "\\Resources\\" + currentProfile.ukr), "ukr");
                ++changesCount;
                writer.WriteLine("{0}. Добавлен украинский язык ввода", changesCount);
            }
            del();
            if (!switchOnT9CB.Checked)
            {
                WriteDataValueToConfigFile("101F876D.txt", "0x7", "0");
                ++changesCount;
                writer.WriteLine("{0}. T9 по умолчанию выключен", changesCount);
            }
            del();
            if (deleteT9CB.Checked)
            {
                string path;
                foreach (string fullLang in langs)
                {
                    path = firmwarePath + "\\sys\\bin\\T9" + CodeToLangEng[fullLang] + ".dll";
                    if (File.Exists(path))
                        File.Delete(path);
                }
            }
            del();
            #endregion
            fwSize = ((double)DirSize(new DirectoryInfo(firmwarePath)) / 1024) / 1024;
            fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
            if (changesCount == 0)
                writer.WriteLine("Изменений нет!");
            writer.Close();
            changesCount = 0;
            if (!string.IsNullOrEmpty(firmwareFilePath))
            {
                currentOperationText.Text = "Текущая операция: Пакую прошивку..";
                BuildFirmware();
            }
            del();
            TimeSpan time = DateTime.Now - startTime;
            currentOperationText.Text = string.Format("Текущая операция: Прошивка модифицирована за {0} мс!", time.TotalMilliseconds);
            if (MessageBox.Show("Прошивка готова! Теперь запакуйте ее в Nokia Editor/Nokia Firmware Editor.") == DialogResult.OK)
            {
                progressBar.Value = 0;
                if (isWinSeven)
                    WindowsFormsExtensions.SetTaskbarProgressState(this, Windows7Taskbar.ThumbnailProgressState.NoProgress);
            }
        }

        /// <summary>
        /// Преобразует список автозагрузки в приемлимый для симбы вид.
        /// </summary>
        /// <remarks>Особо трудная хреновина :-|</remarks>
        private void WriteAutorunList()
        {
            /*int count = 0;
            List<int> pos = new List<int>();
            if (File.Exists(firmwarePath + starterBackgroundPath))
            {
                StreamReader reader = new StreamReader(firmwarePath + starterBackgroundPath);
                char temp;
                char prev = '.';
                string s = string.Empty;
                int i = 0;
                while (!reader.EndOfStream)
                {
                    temp = Convert.ToChar(reader.Read());
                    s += temp.ToString();
                    if (s.Length == 3)
                    {
                        if ((s.Equals("exe") || s.Equals("ex$")) && prev.Equals('.'))
                            pos.Add(i);
                        prev = s[0];
                        s = s.Substring(1, 2);
                    }
                    i++;
                }
                reader.Close();
                reader = new StreamReader(firmwarePath + starterBackgroundPath);
                BinaryReader re = new BinaryReader(reader.BaseStream, Encoding.Default);
                byte[] buf = re.ReadBytes(i);
                for (int j = 0; j < pos.Count; j++)
                {
                    if (autorunCList.GetItemChecked(j))
                        buf[pos[j]] = Convert.ToByte('$');
                }
                reader.Close();
                re.Close();
                count = pos.Count;
                File.WriteAllBytes(firmwarePath + starterBackgroundPath, buf);
            }
            else
            {
                log.AddError("Отсутствует файл: " + firmwarePath + starterBackgroundPath);
            }
            if (File.Exists(firmwarePath + starterNonCriticalPath))
            {
                StreamReader reader = new StreamReader(firmwarePath + starterNonCriticalPath);
                string s = string.Empty;
                char prev = '.';
                char temp;
                int i = 0;
                while (!reader.EndOfStream)
                {
                    temp = Convert.ToChar(reader.Read());
                    s += temp.ToString();
                    if (s.Length == 3)
                    {
                        if ((s.Equals("exe") || s.Equals("ex$")) && prev.Equals('.'))
                            pos.Add(i);
                        prev = s[0];
                        s = s.Substring(1, 2);
                    }
                    i++;
                }
                reader.Close();
                reader = new StreamReader(firmwarePath + starterNonCriticalPath);
                BinaryReader re = new BinaryReader(reader.BaseStream, Encoding.Default);
                byte[] buf2 = re.ReadBytes(i);
                for (int j = count; j < pos.Count; j++)
                {
                    if (autorunCList.GetItemChecked(j))
                        buf2[pos[j]] = Convert.ToByte('$');
                }
                reader.Close();
                re.Close();
                File.WriteAllBytes(firmwarePath + starterNonCriticalPath, buf2);
            }
            else
            {
                log.AddError("Отсутствует файл: " + firmwarePath + starterNonCriticalPath);
            }*/
        }

        private void WriteScriptInit()
        {
            if (File.Exists(firmwarePath + scriptInitPath))
            {
                string[] script = new string[scriptInitList.Lines.Length - 1];
                for (int i = 0; i < scriptInitList.Lines.Length - 1; i++)
                    script[i] = scriptInitList.Lines[i];
                File.WriteAllLines(firmwarePath + scriptInitPath, script, Encoding.Unicode);
            }
            else
            {
                log.AddError("Отсутствует файл: " + firmwarePath + scriptInitPath, new FileNotFoundException("File not found!", firmwarePath + scriptInitPath));
            }
        }

        private void WritePlayerGalleryAndMenuSettings()
        {
            string[] folders = TakeStringArrayFromListBox(playerScanList);
            string str = string.Empty;
            foreach (string s in folders)
            {
                if (!string.IsNullOrEmpty(s))
                    str += s + "|";
            }
            if (!string.IsNullOrEmpty(str))
            {
                str = str.Remove(str.Length - 1);
                if (!str.Equals(playerConfStr))
                {
                    ++changesCount;
                    writer.WriteLine("{0}. Плеер сканирует: {1}", changesCount, str);
                }
            }
            WriteDataValueToConfigFile("101ffcd2.txt", "0x1", str);
            folders = TakeStringArrayFromListBox(galleryScanClist);
            str = string.Empty;
            foreach (string s in folders)
            {
                if (!string.IsNullOrEmpty(s))
                    str += s + ";";
            }
            if (!str.Equals(galleryConfCStr))
            {
                ++changesCount;
                writer.WriteLine("{0}. Галерея не сканирует следующие папки на C: {1}", changesCount, str);
            }
            WriteDataValueToConfigFile("102828AC.txt", "0x1", str);
            folders = TakeStringArrayFromListBox(galleryScanElist);
            str = string.Empty;
            foreach (string s in folders)
            {
                if (!string.IsNullOrEmpty(s))
                    str += s + ";";
            }
            if (!str.Equals(galleryConfEStr))
            {
                ++changesCount;
                writer.WriteLine("{0}. Галерея не сканирует следующие папки на E: {1}", changesCount, str);
            }
            WriteDataValueToConfigFile("102828AC.txt", "0x2", str);
            folders = TakeStringArrayFromListBox(hideAppUidList);
            str = string.Empty;
            foreach (string s in folders)
            {
                if (!string.IsNullOrEmpty(s))
                    str += s + ",";
            }
            if (!string.IsNullOrEmpty(str))
                str = str.Remove(str.Length - 1);
            WriteDataValueToConfigFile("101F8847.txt", "0x8", str);
        }

        private void CopyFontsEffectsAndPatches()
        {
            if (!string.IsNullOrEmpty(fontFolderPath) && fontsCB.Checked)
            {
                string[] fonts = Directory.GetFiles(fontFolderPath, "s60*.ttf", SearchOption.TopDirectoryOnly);
                string filename;
                foreach (string s in fonts)
                {
                    filename = s.Substring(s.LastIndexOf('\\') + 1);
                    File.Copy(s, firmwarePath + "\\resource\\Fonts\\" + filename, true);
                }
                ++changesCount;
                writer.WriteLine("{0}. Заменен стандартный шрифт", changesCount);
            }
            if (!string.IsNullOrEmpty(effectsFolderPath) && effectsEnableCB.Checked)
            {
                string[] effects = Directory.GetFiles(effectsFolderPath);
                string filename;
                foreach (string s in effects)
                {
                    filename = s.Substring(s.LastIndexOf('\\') + 1);
                    File.Copy(s, firmwarePath + "\\resource\\effects\\" + filename, true);
                }
                ++changesCount;
                writer.WriteLine("{0}. Вшиты свои эффекты", changesCount);
            }
            if (!string.IsNullOrEmpty(patchesFolderPath) && patchesCB.Checked)
            {
                string[] patches = Directory.GetFiles(patchesFolderPath, "*.rmp", SearchOption.TopDirectoryOnly);
                if (!Directory.Exists(firmwarePath + "\\Data\\Patches\\"))
                    Directory.CreateDirectory(firmwarePath + "\\Data\\Patches\\");
                string filename;
                foreach (string s in patches)
                {
                    filename = s.Substring(s.LastIndexOf('\\') + 1);
                    File.Copy(s, firmwarePath + "\\Data\\Patches\\" + filename, true);
                }
                if (!fullCB.Checked)
                    AddStringToScriptInit("CP Z:\\Data\\Patches\\* E:\\Patches\\");
            }
        }

        private void WriteDefaultBluetoothName()
        {
            if (!Directory.Exists(firmwarePath + "\\private\\100069CC\\"))
                Directory.CreateDirectory(firmwarePath + "\\private\\100069CC\\");
            string[] s = new string[2];
            s[0] = "DeviceName = " + defBTNameText.Text;
            s[1] = "PageScan = 1";
            File.WriteAllLines(firmwarePath + "\\private\\100069CC\\DefaultBTReg.ini", s);
        }

        private void WriteHeapAndDelayData()
        {
            Directory.CreateDirectory(firmwarePath + "\\private\\10202d56\\");
            CopyFile("sbeconfig.xml", sbeConfigPath);
            if (File.Exists(firmwarePath + sbeConfigPath))
            {
                TextReader reader = new StreamReader(firmwarePath + sbeConfigPath);
                string s = string.Empty;
                s += reader.ReadLine() + Environment.NewLine;
                s += reader.ReadLine() + Environment.NewLine;
                //левый край
                string temp = reader.ReadLine();
                //правый край
                string temp2 = temp.Substring(temp.IndexOf('\"') + 1);
                temp2 = temp2.Substring(temp2.IndexOf('\"'));
                temp = temp.Substring(0, temp.IndexOf('\"') + 1);
                s += temp + heapSizeNUD.Value.ToString() + temp2 + Environment.NewLine;
                s += reader.ReadLine() + Environment.NewLine;
                s += reader.ReadLine() + Environment.NewLine;
                temp = reader.ReadLine();
                temp = temp.Substring(0, temp.IndexOf('\"') + 1);
                temp2 = "\"/>";
                s += temp + appDelayNUD.Value.ToString() + temp2 + Environment.NewLine;
                s += reader.ReadLine();
                reader.Close();
                File.WriteAllText(firmwarePath + sbeConfigPath, s);
            }
            else
            {
                log.AddError("Отсутствует файл: " + firmwarePath + sbeConfigPath, new FileNotFoundException("File not found!", firmwarePath + sbeConfigPath));
            }
        }

        private void WriteDataValueToConfigFile(string confFileName, string strnum, string data)
        {
            if (!data.Equals("null"))
            {
                if (File.Exists(firmwarePath + privateConfigPath + confFileName))
                {
                    string path = firmwarePath + privateConfigPath + confFileName;
                    TextReader reader = new StreamReader(path);
                    string str;
                    string text = string.Empty;
                    while ((str = reader.ReadLine()) != "[Main]")
                        text += str + Environment.NewLine;
                    text += str + Environment.NewLine;
                    while ((str = reader.ReadLine()) != null)
                    {
                        if (str.Substring(0, str.IndexOf(' ')).Equals(strnum, StringComparison.CurrentCultureIgnoreCase))
                        {
                            string[] line = str.Split(new char[] { ' ' });
                            if (line[1].Equals("int"))
                            {
                                string result = line[0] + " " + line[1] + " " + data;
                                for (int i = 3; i < line.Length; i++)
                                    result += " " + line[i];
                                text += result + Environment.NewLine;
                            }
                            else
                            {
                                string result = line[0] + " " + line[1] + " \"" + data + "\"";
                                for (int i = 3; i < line.Length; i++)
                                    result += " " + line[i];
                                text += result + Environment.NewLine;
                            }
                        }
                        else
                            text += str + Environment.NewLine;
                    }
                    reader.Close();
                    try
                    {
                        File.WriteAllText(path, text, Encoding.Unicode);
                    }
                    catch (Exception ex)
                    {
                        log.AddError("Произошла ошибка при записи значения в конфиг.", ex);
                    }
                }
                else
                {
                    log.AddError("Отсутствует файл: " + firmwarePath + privateConfigPath + confFileName, new FileNotFoundException("File not found!", firmwarePath + privateConfigPath + confFileName));
                }
            }
        }

        private void AddJavaCaps()
        {
            CopyDir(new DirectoryInfo(Application.StartupPath + "\\Resources\\JavaCaps\\"), "JavaCaps");
        }

        private void AddAutoInstaller()
        {
            CopyDir(new DirectoryInfo(Application.StartupPath + "\\Resources\\AutoInstaller\\"), "AutoInstaller");
            AddStringToScriptInit("MD E:\\thinkchange\\c\\");
            AddStringToScriptInit("MD E:\\thinkchange\\e\\");
        }

        private void AddRomPatcherPlus()
        {
            CopyDir(new DirectoryInfo(Application.StartupPath + "\\Resources\\RP\\"), "RP");
            if (!Directory.Exists(firmwarePath + "\\Data\\Patches\\"))
                Directory.CreateDirectory(firmwarePath + "\\Data\\Patches\\");
            CopyFile("Open4All RP+.rmp", "\\Data\\Patches\\Open4All RP+.rmp");
            if (!fullInstallserverCB.Checked)
                CopyFile("Install Server RP+.rmp", "\\Data\\Patches\\Install Server RP+.rmp");
            CopyFile("RPPlus.dat", "\\Data\\RPPlus.dat");
            AddStringToScriptInit("CP Z:\\Data\\Patches\\* E:\\Patches\\");
            AddStringToScriptInit("CP Z:\\Data\\RPPlus.dat C:\\System\\data\\");
        }

        private void AddStringToScriptInit(string s)
        {
            int len = scriptInitList.Lines.Length;
            string[] temp = new string[len + 1];
            for (int i = 0; i < len - 1; i++)
                temp[i] = scriptInitList.Lines[i];
            temp[len - 1] = s;
            temp[len] = string.Empty;
            scriptInitList.Lines = temp;
        }

        private void UpdateProgressBar()
        {
            progressBar.PerformStep();
            if (isWinSeven)
                WindowsFormsExtensions.SetTaskbarProgress(this, (float)((double)progressBar.Value * (100.0 / progressBar.Maximum)));
        }

        private void DeleteLanguageFromFirmware()
        {
            if (phoneLangCList.CheckedItems.Count == 0)
            {
                MessageBox.Show("Нельзя удалить все языки!");
                throw new NotSupportedException("Нельзя удалить все языки!");
            }
            else
            {
                currentOperationText.Text = "Текущая операция: Удаляю языки телефона";
                List<string> langsToDelete = ConvertRemoveLangList(true);
                string path;
                string deletedLangs=string.Empty;
                foreach (string lang in langsToDelete)
                {
                    deletedLangs += CodeToLang[lang] + " ";
                    foreach (string s in Directory.GetFiles(firmwarePath + Path.DirectorySeparatorChar, "*.r" + lang, SearchOption.AllDirectories))
                    {
                        string temp = s.Substring(s.LastIndexOf('\\') + 1);
                        if (!temp.Equals("aknfep.r" + lang.ToString()))
                            File.Delete(s);
                    }
                    string ext = "*.o0" + (lang.Length > 2 ? lang : "0" + lang);
                    foreach (string s in Directory.GetFiles(firmwarePath + Path.DirectorySeparatorChar, ext, SearchOption.AllDirectories))
                        File.Delete(s);
                    path = firmwarePath + "\\private\\101F4CD2\\Content\\" + lang;
                    if (Directory.Exists(path))
                        Directory.Delete(path, true);
                    path = firmwarePath + "\\system\\data\\srsf_1_" + lang + ".bin";
                    if (File.Exists(path))
                        File.Delete(path);
                    path = firmwarePath + "\\system\\data\\srsf_4_" + lang + ".bin";
                    if (File.Exists(path))
                        File.Delete(path);
                    foreach (string s in Directory.GetFiles(firmwarePath + Path.DirectorySeparatorChar, "*.h" + lang, SearchOption.AllDirectories))
                        File.Delete(s);
                    path = firmwarePath + "\\resource\\applicationhelps\\" + lang;
                    if (Directory.Exists(path))
                        Directory.Delete(path, true);
                    path = firmwarePath + "\\resource\\xhtml\\" + lang;
                    if (Directory.Exists(path))
                        Directory.Delete(path, true);
                }
                if (!string.IsNullOrEmpty(deletedLangs))
                {
                    deletedLangs = deletedLangs.Remove(deletedLangs.Length - 1);
                    ++changesCount;
                    writer.WriteLine("{0}. Удалены языки телефона: {1}", changesCount, deletedLangs);
                }
            }
            currentOperationText.Text = "Текущая операция: Удаляю языки ввода";
            DeleteInputLanguageFromFirmware();
            currentOperationText.Text = "Текущая операция: Удаляю языки справки";
            DeleteHelpLanguageFromFirmware();
            currentOperationText.Text = "Текущая операция: Редактирую languages.txt";
            RemoveLangFromTxt();
        }

        private void DeleteHelpLanguageFromFirmware()
        {
            List<string> langsToDelete = ConvertRemoveHelpLangList();
            string path;
            string deletedLangs = string.Empty;
            foreach (string lang in langsToDelete)
            {
                deletedLangs += CodeToLang[lang] + " ";
                foreach (string s in Directory.GetFiles(firmwarePath + Path.DirectorySeparatorChar, "*.h" + lang, SearchOption.AllDirectories))
                    File.Delete(s);
                path = firmwarePath + "\\resource\\applicationhelps\\" + lang;
                if (Directory.Exists(path))
                    Directory.Delete(path, true);
                path = firmwarePath + "\\resource\\xhtml\\" + lang;
                if (Directory.Exists(path))
                    Directory.Delete(path, true);
            }
            if (!string.IsNullOrEmpty(deletedLangs))
                deletedLangs = deletedLangs.Remove(deletedLangs.Length - 1);
            ++changesCount;
            writer.WriteLine("{0}. Удалена справка на языках: {1}", changesCount, deletedLangs);
        }

        private void DeleteInputLanguageFromFirmware()
        {
            List<string> langsToDelete = ConvertRemoveInputLangList(true);
            string path;
            foreach (string fullLang in langsToDelete)
            {
                path = firmwarePath + "\\sys\\bin\\T9" + fullLang + ".dll";
                if (File.Exists(path))
                    File.Delete(path);
                path = firmwarePath + "\\resource\\qwerty\\PtiQwerty" + fullLang + ".rsc";
                if (File.Exists(path))
                    File.Delete(path);
                path = firmwarePath + "\\resource\\multitap\\Pti" + fullLang + ".rsc";
                if (File.Exists(path))
                    File.Delete(path);
            }
            langsToDelete = ConvertRemoveInputLangList(false);
            string deletedLangs = string.Empty;
            foreach (string lang in langsToDelete)
            {
                deletedLangs += CodeToLang[lang] + " ";
                path = firmwarePath + "\\resource\\plugins\\peninputhwrwindowconfiginfo_" + lang + ".rsc";
                if (File.Exists(path))
                    File.Delete(path);
                path = firmwarePath + "\\resource\\plugins\\peninputvkbwindowconfiginfo_" + lang + ".rsc";
                if (File.Exists(path))
                    File.Delete(path);
                path = firmwarePath + "\\resource\\fep\\aknfep.r" + lang;
                if (File.Exists(path))
                    File.Delete(path);
                path = firmwarePath + "\\sys\\bin\\Elocl." + lang;
                if (File.Exists(path))
                    File.Delete(path);
            }
            deletedLangs = deletedLangs.Remove(deletedLangs.Length - 1);
            ++changesCount;
            writer.WriteLine("{0}. Удалены языки ввода: {1}", changesCount, deletedLangs);
        }

        private List<string> ConvertRemoveLangList(bool isLangToDeleteReturn)
        {
            defaultlanguage = LangToCode[Convert.ToString(defLangCombo.SelectedItem)];
            List<string> langs = new List<string>();
            List<string> delLangs = new List<string>();
            for (int i = 0; i < phoneLangCList.Items.Count; i++)
            {
                if (phoneLangCList.GetItemChecked(i))
                    langs.Add(LangToCode[Convert.ToString(phoneLangCList.Items[i])]);
                else
                    delLangs.Add(LangToCode[Convert.ToString(phoneLangCList.Items[i])]);
            }
            if (!isLangToDeleteReturn)
                return langs;
            else
                return delLangs;
        }

        private List<string> ConvertRemoveHelpLangList()
        {
            List<string> delLangs = new List<string>();
            for (int i = 0; i < helpLangCList.Items.Count; i++)
            {
                if (!helpLangCList.GetItemChecked(i) && phoneLangCList.GetItemChecked(i))
                    delLangs.Add(LangToCode[Convert.ToString(helpLangCList.Items[i])]);
            }
            return delLangs;
        }

        private List<string> ConvertRemoveInputLangList(bool isFullLangNameToReturn)
        {
            List<string> delLangs = new List<string>();
            List<string> delLangs2 = new List<string>();
            for (int i = 0; i < inputLangCList.Items.Count; i++)
            {
                if (!inputLangCList.GetItemChecked(i))
                {
                    delLangs.Add(CodeToLangEng[LangToCode[Convert.ToString(inputLangCList.Items[i])]]);
                    delLangs2.Add(LangToCode[Convert.ToString(helpLangCList.Items[i])]);
                }
            }
            if (isFullLangNameToReturn)
                return delLangs;
            else
                return delLangs2;
        }

        private void RemoveLangFromTxt()
        {
            if (File.Exists(firmwarePath + "\\resource\\Bootdata\\languages.txt"))
            {
                string str;
                string str2 = "";
                string filePath = firmwarePath + "\\resource\\Bootdata\\languages.txt";
                TextReader reader = new StreamReader(filePath);
                List<string> list = ConvertRemoveLangList(false);
                while ((str = reader.ReadLine()) != null)
                {
                    foreach (string s in list)
                    {
                        if (str.Contains(s))
                        {
                            if (str.Contains(",d"))
                            {
                                str = str.Remove(2);
                            }
                            if (str.Contains(defaultlanguage))
                            {
                                str = str + ",d";
                            }
                            str2 = str2 + str + Environment.NewLine;
                        }
                    }
                }
                reader.Close();
                str2 = str2.Trim().Trim();
                str2 += Environment.NewLine;
                File.WriteAllText(filePath, str2, Encoding.Unicode);
            }
            else
            {
                log.AddError("Отсутствует файл: " + firmwarePath + "\\resource\\Bootdata\\languages.txt", new FileNotFoundException("File not found!", firmwarePath + "\\resource\\Bootdata\\languages.txt"));
            }
        }

        private void effectsSelectButton_Click(object sender, EventArgs e)
        {
            if (selectEffectsDialog.ShowDialog() == DialogResult.OK)
            {
                effectsFolderPath = selectEffectsDialog.SelectedPath;
                fwSize += (((double)DirSize(new DirectoryInfo(effectsFolderPath))) / 1024) / 1024;
                fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
            }
            else
                MessageBox.Show("Произошла какая-то ошибка. Выберите папку еще раз.");
        }

        private void fontSelectButton_Click(object sender, EventArgs e)
        {
            if (selectFontsDialog.ShowDialog() == DialogResult.OK)
            {
                fontFolderPath = selectFontsDialog.SelectedPath;
                fwSize += (((double)DirSize(new DirectoryInfo(fontFolderPath))) / 1024) / 1024;
                fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
            }
            else
                MessageBox.Show("Произошла какая-то ошибка. Выберите папку еще раз.");
        }

        private void patchesCB_CheckedChanged(object sender, EventArgs e)
        {
            patchesSelectButton.Enabled = !patchesSelectButton.Enabled;
            if (patchesCB.Checked)
                MessageBox.Show("Выберите папку с патчами.");
            else if (!string.IsNullOrEmpty(patchesFolderPath))
            {
                fwSize -= (((double)DirSize(new DirectoryInfo(patchesFolderPath))) / 1024) / 1024;
                fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
                patchesFolderPath = string.Empty;
            }
        }

        private void patchesSelectButton_Click(object sender, EventArgs e)
        {
            if (selectPatchesDialog.ShowDialog() == DialogResult.OK)
            {
                patchesFolderPath = selectPatchesDialog.SelectedPath;
                fwSize += (((double)DirSize(new DirectoryInfo(patchesFolderPath))) / 1024) / 1024;
                fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
            }
            else
                MessageBox.Show("Произошла какая-то ошибка. Выберите папку еще раз.");
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new About().ShowDialog();
        }

        private void cacheToERadio_CheckedChanged(object sender, EventArgs e)
        {
            cacheToCRadio.Checked = !cacheToERadio.Checked;
        }

        private void cacheToCRadio_CheckedChanged(object sender, EventArgs e)
        {
            cacheToERadio.Checked = !cacheToCRadio.Checked;
        }

        private void autorunEnableCB_CheckedChanged(object sender, EventArgs e)
        {
            /*autorunCList.Enabled = autorunEnableCB.Checked;
            if (autorunEnableCB.Checked == true)
            {
                autorun = new List<string>();
                CopyFile("starter_background_apps.rsc", starterBackgroundPath);
                CopyFile("starter_non_critical_1.rsc", starterNonCriticalPath);
                LoadStarterFile(starterBackgroundPath);
                LoadStarterFile(starterNonCriticalPath);
                InitBootList();
            }
            else
                autorunCList.Items.Clear();*/
        }

        private void saveConfigToolStripMenuItem_Click(object sender, EventArgs e)
        {
            config.ClearConfigClass();
            config.InitConfigInfo();
            config.SaveConfig();
            MessageBox.Show("Настройки сохранены!");
        }

        private void loadConfigToolStripMenuItem_Click(object sender, EventArgs e)
        {
            config.LoadConfig();
            MessageBox.Show("Настройки загружены!");
        }

        private void phoneLangCList_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            helpLangCList.SetItemCheckState(e.Index, e.NewValue);
            if (e.NewValue == CheckState.Unchecked)
                ChangeFwSize(-1, 1);
            else
                ChangeFwSize(1, 1);
        }

        private void fwSizeText_TextChanged(object sender, EventArgs e)
        {
            if (fwSize > 33.0)
                MessageBox.Show("Размер вашей прошивки превысил 33 МБ! Уберите что-нибудь из прошивки, иначе при прошивке получите труп!");
            freeSpace = 33.0 - Math.Round(fwSize, 1);
            freeSpaceText.Text = string.Format("Своб. место: {0} МБ", freeSpace);
        }

        private void fullCB_CheckedChanged(object sender, EventArgs e)
        {
            ChangeFwSize(fullCB, 0.165);
        }

        private void sisCapsCB_CheckedChanged(object sender, EventArgs e)
        {
            ChangeFwSize(sisCapsCB, 0.0009);
        }

        private void ChangeFwSize(CheckBox c, double amountSize)
        {
            if (c.Checked)
            {
                fwSize += amountSize;
                fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
            }
            else
            {
                fwSize -= amountSize;
                fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
            }
        }

        private void ChangeFwSize(int count, int mode)
        {
            switch (mode)
            {
                case 1:
                    fwSize += count * 2.51;
                    break;
                case 2:
                    fwSize += count * 0.12;
                    break;
                case 3:
                    fwSize += count * 1.0;
                    break;
                default:
                    break;
            }
            fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
        }

        private void javaCapsCB_CheckedChanged(object sender, EventArgs e)
        {
            ChangeFwSize(javaCapsCB, 0.038);
        }

        private void sisTransferProtectionCB_CheckedChanged(object sender, EventArgs e)
        {
            ChangeFwSize(sisTransferProtectionCB, 0.0006);
        }

        private void disableLightAndVibraCB_CheckedChanged(object sender, EventArgs e)
        {
            ChangeFwSize(disableLightAndVibraCB, 0.042);
        }

        private void addAutoInstCB_CheckedChanged(object sender, EventArgs e)
        {
            ChangeFwSize(addAutoInstCB, 0.075);
        }

        private void increaseSysCacheCB_CheckedChanged(object sender, EventArgs e)
        {
            ChangeFwSize(increaseSysCacheCB, 0.0038);
        }

        private void inputLangCList_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            if (e.NewValue == CheckState.Unchecked)
                ChangeFwSize(-1, 2);
            else
                ChangeFwSize(1, 2);
        }

        private void copyOwnFilesCB_CheckedChanged(object sender, EventArgs e)
        {
            if (copyOwnFilesCB.Checked)
            {
                fwSize += (((double)DirSize(new DirectoryInfo(Application.StartupPath + "\\YourFiles\\"))) / 1024) / 1024;
                fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
            }
            else
            {
                fwSize -= (((double)DirSize(new DirectoryInfo(Application.StartupPath + "\\YourFiles\\"))) / 1024) / 1024;
                fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
            }
        }

        private string ConvertBoolToString(bool input)
        {
            if (input)
                return "Включен";
            else
                return "Отключен";
        }

        private void startupSoundCB_CheckedChanged(object sender, EventArgs e)
        {
            selectStartupSoundBitton.Enabled = startupSoundCB.Checked;
            if (!string.IsNullOrEmpty(startupSoundPath) && !startupSoundCB.Checked)
            {
                fwSize -= (((double)new FileInfo(startupSoundPath).Length) / 1024) / 1024;
                fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
                fontFolderPath = string.Empty;
            }
        }

        private void selectStartupSoundBitton_Click(object sender, EventArgs e)
        {
            if (openSoundDialog.ShowDialog() == DialogResult.OK)
            {
                startupSoundPath = openSoundDialog.FileName;
                fwSize += (((double)new FileInfo(startupSoundPath).Length) / 1024) / 1024;
                fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
            }
        }

        private void startupSplashCB_CheckedChanged(object sender, EventArgs e)
        {
            selectStartupSplashButton.Enabled = startupSplashCB.Checked;
            if (!string.IsNullOrEmpty(startupSplashPath) && !startupSplashCB.Checked)
            {
                fwSize -= (((double)new FileInfo(startupSplashPath).Length) / 1024) / 1024;
                fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
                fontFolderPath = string.Empty;
            }
        }

        private void selectStartupSplashButton_Click(object sender, EventArgs e)
        {
            if (openStartupSplashDialog.ShowDialog() == DialogResult.OK)
            {
                startupSplashPath = openStartupSplashDialog.FileName;
                fwSize += (((double)new FileInfo(startupSplashPath).Length) / 1024) / 1024;
                fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
            }
        }

        private void shutdownSplashCB_CheckedChanged(object sender, EventArgs e)
        {
            selectShutdownSplashButton.Enabled = shutdownSplashCB.Checked;
            if (!string.IsNullOrEmpty(shutdownSplashPath) && !shutdownSplashCB.Checked)
            {
                fwSize -= (((double)new FileInfo(shutdownSplashPath).Length) / 1024) / 1024;
                fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
                fontFolderPath = string.Empty;
            }
        }

        private void selectShutdownSplashButton_Click(object sender, EventArgs e)
        {
            if (openShutdownSplashDialog.ShowDialog() == DialogResult.OK)
            {
                shutdownSplashPath = openShutdownSplashDialog.FileName;
                fwSize += (((double)new FileInfo(shutdownSplashPath).Length) / 1024) / 1024;
                fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
            }
        }

        private void addRusLangCB_CheckedChanged(object sender, EventArgs e)
        {
            ChangeFwSize(addRusLangCB, 0.124);
        }

        private void addUkrLangCB_CheckedChanged(object sender, EventArgs e)
        {
            ChangeFwSize(addUkrLangCB, 0.129);
        }

        private void selectOwnMenuFileCB_CheckedChanged(object sender, EventArgs e)
        {
            selectAppshelldataFile.Enabled = selectOwnMenuFileCB.Checked;
            if (!string.IsNullOrEmpty(menuFilePath) && !selectOwnMenuFileCB.Checked)
            {
                fwSize -= (((double)new FileInfo(menuFilePath).Length) / 1024) / 1024;
                fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
                fontFolderPath = string.Empty;
            }
        }

        private void selectAppshelldataFile_Click(object sender, EventArgs e)
        {
            if (openMenuFileDialog.ShowDialog() == DialogResult.OK)
            {
                menuFilePath = openMenuFileDialog.FileName;
                fwSize += (((double)new FileInfo(menuFilePath).Length) / 1024) / 1024;
                fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
            }
        }

        private void tornadoCB_CheckedChanged(object sender, EventArgs e)
        {
            tsunamiCB.Enabled = tornadoCB.Checked;
            if (!tornadoCB.Checked)
                tsunamiCB.Checked = false;
            ChangeFwSize(tornadoCB, 0.808);
            if (tornadoCB.Checked)
                homeScreensDefaultCombo.Items.Add((object)"Orange Tornado");
            else
                homeScreensDefaultCombo.Items.Remove((object)"Orange Tornado");
        }

        private void tsunamiCB_CheckedChanged(object sender, EventArgs e)
        {
            ChangeFwSize(tsunamiCB, 1.090);
            if (tsunamiCB.Checked)
                homeScreensDefaultCombo.Items.Add((object)"Orange Tsunami");
            else
                homeScreensDefaultCombo.Items.Remove((object)"Orange Tsunami");
        }

        private void vodafoneCB_CheckedChanged(object sender, EventArgs e)
        {
            ChangeFwSize(vodafoneCB, 1.350);
            if (vodafoneCB.Checked)
                homeScreensDefaultCombo.Items.Add((object)"Vodafone");
            else
                homeScreensDefaultCombo.Items.Remove((object)"Vodafone");
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            new DirectoryInfo(Application.StartupPath + "\\temp\\").Delete(true);
            new DirectoryInfo(Application.StartupPath + "\\rofs2\\").Delete(true);
            new DirectoryInfo(Application.StartupPath + "\\exe\\temp\\").Delete(true);
            Directory.CreateDirectory(Application.StartupPath + "\\temp\\");
            Directory.CreateDirectory(Application.StartupPath + "\\rofs2\\");
            Directory.CreateDirectory(Application.StartupPath + "\\exe\\temp\\");
            if (log.GetErrorCount() > 0)
            {
                MessageBox.Show("Во время выполнения программы произошли ошибки. Подробнее об этих ошибках в log.txt");
                log.WriteLog();
            }
        }

        private void clearButton_Click(object sender, EventArgs e)
        {
            softList.Items.Clear();
        }

        private void deleteSoftButton_Click(object sender, EventArgs e)
        {
            object[] items = new object[softList.Items.Count - 1];
            int j = 0;
            for (int i = 0; i < softList.Items.Count; i++)
            {
                if (!softList.Items[i].Equals(softList.SelectedItem))
                {
                    items[j] = softList.Items[i];
                    j++;
                }
            }
            softList.Items.Clear();
            foreach (object o in items)
                softList.Items.Add(o);
        }

        private void addSoftButton_Click(object sender, EventArgs e)
        {
            new AddSoftDialog(this).Show();
        }

        public void AddSoft(string data)
        {
            softList.Items.Add((object)data);
            NormDir(new DirectoryInfo(Application.StartupPath + "\\temp\\"));
        }

        private void startupSoundVolumeSlider_Scroll(object sender, EventArgs e)
        {
            label63.Text = "Гром-ть звука включения (" + startupSoundVolumeSlider.Value.ToString() + "):";
        }

        private void deletePlayerFolderButton_Click(object sender, EventArgs e)
        {
            playerScanList.Items.Remove(playerScanList.SelectedItem);
        }

        private void addPlayerFolderButton_Click(object sender, EventArgs e)
        {
            new AddPlayerFolderDialog(playerScanList).Show();
        }

        private void removeUidButton_Click(object sender, EventArgs e)
        {
            hideAppUidList.Items.Remove(hideAppUidList.SelectedItem);
        }

        private void addUidButton_Click(object sender, EventArgs e)
        {
            new AddUidDialog(hideAppUidList).Show();
        }

        private void deleteFromCListButton_Click(object sender, EventArgs e)
        {
            galleryScanClist.Items.Remove(galleryScanClist.SelectedItem);
        }

        private void deleteFromEListButton_Click(object sender, EventArgs e)
        {
            galleryScanElist.Items.Remove(galleryScanElist.SelectedItem);
        }

        private void addToCListButton_Click(object sender, EventArgs e)
        {
            new AddGalleryFolder(galleryScanClist).Show();
        }

        private void addToEListButton_Click(object sender, EventArgs e)
        {
            new AddGalleryFolder(galleryScanElist).Show();
        }

        private void CreateObeyFile()
        {
            //Написать обход всех папок и создание файла вида:
            //
            //rofssize=0x10000000
            //version=0,01
            //rofsname="путь до конечного образа"
            //data=".\ROFS2\private\10009d8f\ecom-2-0.spi" "\private\10009d8f\ecom-2-0.spi"
            //И так все файлы..
            string obey = string.Empty;
            List<string> fileList = new List<string>();
            GetFileList(new DirectoryInfo(rofs2FolderPath), ref fileList);

            StringBuilder str = new StringBuilder("rofssize=0x10000000");
            str.Append(Environment.NewLine);
            str.Append("version=0,01");
            str.Append(Environment.NewLine);
            str.Append("rofsname=\"");
            str.Append(rofs2NewImagePath);
            str.Append("\"");
            str.Append(Environment.NewLine);
            foreach (string s in fileList)
                str.Append(BuildDataString(TrimString(s, "rofs2", true), TrimString(s, "rofs2", false)));
            obey = str.ToString();

            File.WriteAllText(obeyFilePath, obey, Encoding.Default);
        }

        private void ConvertFirmwareToImage()
        {
            FileStream file = new FileStream(firmwareFilePath, FileMode.Open);
            int size = (int)file.Length;
            byte[] fileBytes = new byte[size];
            file.Read(fileBytes, 0, size);
            file.Close();
            //Далее - отрезаем первые 9790 байт файла
            size -= 9790;
            byte[] newFileBytes = new byte[size];
            int j = -1;
            for (int i = 9790; i < fileBytes.Length; i++)
                newFileBytes[++j] = fileBytes[i];
            //Запомним отрезанный заголовок
            j = -1;
            firstHeader = new byte[9790];
            for (int i = 0; i < 9790; i++)
                firstHeader[++j] = fileBytes[i];

            byte[] otherBytes = new byte[size];
            headers = 0;
            int offset = 262144;
            int dx = 262144;
            int k=-1;
            for (int i = 0; i < 259072; i++)
                otherBytes[++k] = newFileBytes[i];
            for (int i = 259091; i < newFileBytes.Length; i += dx + 19)
            {
                if (i + offset < newFileBytes.Length)
                {
                    for (j = i; j < i + offset; j++)
                        otherBytes[++k] = newFileBytes[j];
                    ++headers;
                }
                else
                {
                    for (j = i; j < newFileBytes.Length; j++)
                        otherBytes[++k] = newFileBytes[j];
                    ++headers;
                    break;
                }
            }
            byte[] totalBytes = new byte[size - (19 * headers)];
            for (int i = 0; i < totalBytes.Length; i++)
                totalBytes[i] = otherBytes[i];
            FileStream output = new FileStream(rofs2ImagePath, FileMode.Create);
            output.Write(totalBytes, 0, totalBytes.Length);
            output.Close();
        }

        private void UnpackFirmware()
        {
            ConvertFirmwareToImage();
            //Распаковываем rofs2.img получаем папки с файлами
            string param = @"-z .\rofs2\ .\exe\temp\rofs2.img";

            ProcessStartInfo exe = new ProcessStartInfo(readImagePath, param);
            exe.CreateNoWindow = true;
            exe.WindowStyle = ProcessWindowStyle.Hidden;
            exe.WorkingDirectory = Application.StartupPath;
            using (Process p = Process.Start(exe))
                p.WaitForExit();
        }

        private void BuildFirmware()
        {
            CreateObeyFile();
            string param = @".\exe\temp\rofs2.obey";

            ProcessStartInfo exe = new ProcessStartInfo(rofsBuildPath, param);
            exe.CreateNoWindow = true;
            exe.WindowStyle = ProcessWindowStyle.Hidden;
            exe.WorkingDirectory = Application.StartupPath;
            using (Process p = Process.Start(exe))
                p.WaitForExit();
            ConvertImageToFirmware();
        }

        private void ConvertImageToFirmware()
        {
            FileStream input = new FileStream(rofs2NewImagePath, FileMode.Open);
            int size = (int)input.Length;
            int h = 0;
            //Подсчитаем кол-во дпополнительных заголовков
            for (int i = 259091; i < size; i += 262144 + 19)
                ++h;
            int totalSize = size + 9790 + (19 * h) + 416;
            byte[] totalFileBytes = new byte[totalSize];
            byte[] fileBytes = new byte[size];
            input.Read(fileBytes, 0, size);
            input.Close();
            int offset = 262144;
            int dx = 262144;
            //Пришиваем первый заголовок
            for (int i = 0; i < 9790; i++)
                totalFileBytes[i] = firstHeader[i];
            int j = -1;
            //Считываем данные до места второго заголовка
            for (int i = 9790; i < 259072 + 9790; i++)
                totalFileBytes[i] = fileBytes[++j];
            //Считываем данные, попутно вставляю остальные заголовки
            for (int i = 259091 + 9790; i < totalFileBytes.Length; i+= dx + 19)
            {
                int m = -1;
                for (int k = i - 19; k < i; k++)
                    totalFileBytes[k] = otherHeader[++m];
                if (i + offset < totalFileBytes.Length)
                {
                    for (int k = i; k < i + offset; k++)
                        totalFileBytes[k] = fileBytes[++j];
                }
                else
                {
                    //Считываем остаток данных
                    for (int k = i; k < totalFileBytes.Length - 416; k++)
                        totalFileBytes[k] = fileBytes[++j];
                    //Забиваем концовку битами
                    for (int k = totalFileBytes.Length - 416; k < totalFileBytes.Length; k++)
                        totalFileBytes[k] = (byte)255;
                    break;
                }
            }
            string filename = "[Mod]" + firmwareFilePath.Substring(firmwareFilePath.LastIndexOf('\\') + 1);
            FileStream output = new FileStream(Application.StartupPath + "\\" + filename, FileMode.Create);
            output.Write(totalFileBytes, 0, totalFileBytes.Length);
            output.Close();
        }

        private string BuildDataString(string source, string destination)
        {
            StringBuilder str = new StringBuilder("data=\".");
            str.Append(source);
            str.Append("\" \"");
            str.Append(destination);
            str.Append("\"");
            str.Append(Environment.NewLine);
            return str.ToString();
        }

        private string TrimString(string s, string root, bool includeRoot)
        {
            string[] dirs = s.Split(new char[] { '\\' });
            int i = 0;
            string result = "\\";
            do
                i++;
            while (!dirs[i].Equals(root));
            if(!includeRoot)
                i++;
            while (i < dirs.Length)
            {
                result += dirs[i] + "\\";
                i++;
            }
            result = result.Substring(0, result.Length - 1);
            return result;
        }

        private void openFWMenuItem_Click(object sender, EventArgs e)
        {
            currentOperationText.Text = "Текущая операция: Распаковываю прошивку..";
            if (isLoad)
            {
                isLoad = false;
                ProgrammReset();
            }
            if (openFwDialog.ShowDialog() == DialogResult.OK)
            {
                firmwareFilePath = openFwDialog.FileName;
                UnpackFirmware();
                firmwarePath = rofs2FolderPath;
                if (Directory.Exists(firmwarePath + "\\private\\"))
                {
                    isLoad = true;
                    cookToolStripMenuItem.Enabled = true;
                    LoadLangSupportByFirmware();
                    DetectLangList();
                    InitLang();
                    defThemeUidText.Text = ReadDataValueFromConfigFile("101F876F.txt", "0x14");
                    PutStringArrayIntoListBox(ReadHiddenAppsUids(), hideAppUidList);
                    PutStringArrayIntoListBox(ReadScanDirs("0x1", "101FFCD2.txt", '|'), playerScanList);
                    PutStringArrayIntoListBox(ReadScanDirs("0x1", "102828AC.txt", ';'), galleryScanClist);
                    PutStringArrayIntoListBox(ReadScanDirs("0x2", "102828AC.txt", ';'), galleryScanElist);
                    scriptInitList.Lines = ReadScriptInit();
                    fwSize = ((double)DirSize(new DirectoryInfo(firmwarePath)) / 1024) / 1024;
                    fwSizeText.Text = string.Format("Испол. места: {0} МБ", Math.Round(fwSize, 1));
                    config.InitConfigInfo();
                    contentTab.Enabled = true;
                    currentOperationText.Text = "Текущая операция: *бездействие*";
                    if (log.GetErrorCount() > 0)
                        MessageBox.Show("При открытии произошли следующие ошибки:" + Environment.NewLine + Environment.NewLine + log.ToString());
                }
                else
                    MessageBox.Show("Вы открыли неверную папку! Попробуйте еще раз.");
            }
        }

        private void killMenuKineticCB_CheckedChanged(object sender, EventArgs e)
        {
            ChangeFwSize(killMenuKineticCB, 0.15);
        }

        private void deleteT9CB_CheckedChanged(object sender, EventArgs e)
        {
            switchOnT9CB.Enabled = !deleteT9CB.Checked;
            switchOnT9CB.Checked = !deleteT9CB.Checked;
        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            label51.Text = "Громкость плеера (" + playerVolumeSlider.Value + ")";
        }

        private void removeCameraSoundsCB_CheckedChanged(object sender, EventArgs e)
        {
            ChangeFwSize(removeCameraSoundsCB, 0.016);
        }

        private void perfProfileCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            ApplyPerfomanceProfile(perfProfileCombo.SelectedIndex);
        }

        private void disableKineticCB_CheckedChanged(object sender, EventArgs e)
        {
            if (disableKineticCB.Checked)
            {
                killMenuKineticCB.Checked = false;
                killMenuKineticCB.Enabled = false;
            }
            else
                killMenuKineticCB.Enabled = true;
        }

        private void kineticProfileCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            ApplyKineticProfile(kineticProfileCombo.SelectedIndex);
        }

        private void numbersRadio_CheckedChanged(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                string[] sym = symbols[numberPos];
                int k = 0;
                foreach (Button b in buttons)
                {
                    if (k < keyboardLength)
                        b.Text = sym[k];
                    k++;
                }
            }
        }

        private void generalRadio_CheckedChanged(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                string[] sym = symbols[0];
                int k = 0;
                foreach (Button b in buttons)
                {
                    if (k < keyboardLength)
                        b.Text = sym[k];
                    k++;
                }
            }
        }

        private void generalBigRadio_CheckedChanged(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                string[] sym = symbols[1];
                int k = 0;
                foreach (Button b in buttons)
                {
                    if (k < keyboardLength)
                        b.Text = sym[k];
                    k++;
                }
            }
        }

        private void numbersBigRadio_CheckedChanged(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                string[] sym = symbols[numberBigPos];
                int k = 0;
                foreach (Button b in buttons)
                {
                    if (k < keyboardLength)
                        b.Text = sym[k];
                    k++;
                }
            }
        }

        private void ieroOneRadio_CheckedChanged(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                string[] sym = symbols[ieroOnePos];
                int k = 0;
                foreach (Button b in buttons)
                {
                    if (k < keyboardLength)
                        b.Text = sym[k];
                    k++;
                }
            }
        }

        private void ieroOneBigRadio_CheckedChanged(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                string[] sym = symbols[ieroOneBigPos];
                int k = 0;
                foreach (Button b in buttons)
                {
                    if (k < keyboardLength)
                        b.Text = sym[k];
                    k++;
                }
            }
        }

        private void ieroTwoRadio_CheckedChanged(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                string[] sym = symbols[6];
                int k = 0;
                foreach (Button b in buttons)
                {
                    if (k < keyboardLength)
                        b.Text = sym[k];
                    k++;
                }
            }
        }

        private void ieroTwoBigRadio_CheckedChanged(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                string[] sym = symbols[7];
                int k = 0;
                foreach (Button b in buttons)
                {
                    if (k < keyboardLength)
                        b.Text = sym[k];
                    k++;
                }
            }
        }

        private void ieroThreeRadio_CheckedChanged(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                string[] sym = symbols[8];
                int k = 0;
                foreach (Button b in buttons)
                {
                    if (k < keyboardLength)
                        b.Text = sym[k];
                    k++;
                }
            }
        }

        private void ieroThreeBigRadio_CheckedChanged(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                string[] sym = symbols[9];
                int k = 0;
                foreach (Button b in buttons)
                {
                    if (k < keyboardLength)
                        b.Text = sym[k];
                    k++;
                }
            }
        }

        private void saveKeyboardButton_Click(object sender, EventArgs e)
        {
            string lcode = LangToCode[keyboardLangsCombo.SelectedItem.ToString()];
            Directory.CreateDirectory(Application.StartupPath + "\\temp\\keys\\");
            ApplyChangesToTheKeyboardFile(Application.StartupPath + "\\temp\\keys\\peninputvkbwindowconfiginfo_" + lcode + ".rsc");
        }

        private void editKeyboardCB_CheckedChanged(object sender, EventArgs e)
        {
            if (editKeyboardCB.Checked)
            {
                langSmallKeyboard.Enabled = true;
                saveKeyboardButton.Enabled = true;
                keyboardLangsCombo.Enabled = true;
                generalRadio.Enabled = true;
                generalBigRadio.Enabled = true;
                numbersBigRadio.Enabled = true;
                numbersRadio.Enabled = true;
                ieroOneBigRadio.Enabled = true;
                ieroOneRadio.Enabled = true;
                ieroTwoRadio.Enabled = true;
                ieroTwoBigRadio.Enabled = true;
                ieroThreeRadio.Enabled = true;
                ieroThreeBigRadio.Enabled = true;
                foreach (object o in inputLangCList.CheckedItems)
                    keyboardLangsCombo.Items.Add(o);
                keyboardLangsCombo.SelectedIndex = 0;
                //ChangeKeyboard(LangToCode[keyboardLangsCombo.SelectedItem.ToString()]);
            }
            else
            {
                langSmallKeyboard.Enabled = false;
                saveKeyboardButton.Enabled = false;
                keyboardLangsCombo.Enabled = false;
                generalRadio.Enabled = false;
                generalBigRadio.Enabled = false;
                numbersBigRadio.Enabled = false;
                numbersRadio.Enabled = false;
                ieroOneBigRadio.Enabled = false;
                ieroOneRadio.Enabled = false;
                ieroTwoRadio.Enabled = false;
                ieroTwoBigRadio.Enabled = false;
                ieroThreeRadio.Enabled = false;
                ieroThreeBigRadio.Enabled = false;
                keyboardLangsCombo.Items.Clear();
            }
        }

        private void keyboardLangsCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            ChangeKeyboard(LangToCode[keyboardLangsCombo.SelectedItem.ToString()]);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button1).ShowDialog();
                ApplyChanges();
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button2).ShowDialog();
                ApplyChanges();
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button3).ShowDialog();
                ApplyChanges();
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button4).ShowDialog();
                ApplyChanges();
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button5).ShowDialog();
                ApplyChanges();
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button6).ShowDialog();
                ApplyChanges();
            }
        }

        private void button7_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button7).ShowDialog();
                ApplyChanges();
            }
        }

        private void button8_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button8).ShowDialog();
                ApplyChanges();
            }
        }

        private void button9_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button9).ShowDialog();
                ApplyChanges();
            }
        }

        private void button10_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button10).ShowDialog();
                ApplyChanges();
            }
        }

        private void button11_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button11).ShowDialog();
                ApplyChanges();
            }
        }

        private void button12_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button12).ShowDialog();
                ApplyChanges();
            }
        }

        private void button13_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button13).ShowDialog();
                ApplyChanges();
            }
        }

        private void button14_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button14).ShowDialog();
                ApplyChanges();
            }
        }

        private void button15_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button15).ShowDialog();
                ApplyChanges();
            }
        }

        private void button16_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button16).ShowDialog();
                ApplyChanges();
            }
        }

        private void button17_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button17).ShowDialog();
                ApplyChanges();
            }
        }

        private void button18_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button18).ShowDialog();
                ApplyChanges();
            }
        }

        private void button19_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button19).ShowDialog();
                ApplyChanges();
            }
        }

        private void button20_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button20).ShowDialog();
                ApplyChanges();
            }
        }

        private void button21_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button21).ShowDialog();
                ApplyChanges();
            }
        }

        private void button22_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button22).ShowDialog();
                ApplyChanges();
            }
        }

        private void button23_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button23).ShowDialog();
                ApplyChanges();
            }
        }

        private void button24_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button24).ShowDialog();
                ApplyChanges();
            }
        }

        private void button25_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button25).ShowDialog();
                ApplyChanges();
            }
        }

        private void button26_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button26).ShowDialog();
                ApplyChanges();
            }
        }

        private void button27_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button27).ShowDialog();
                ApplyChanges();
            }
        }

        private void button28_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button28).ShowDialog();
                ApplyChanges();
            }
        }

        private void button29_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button29).ShowDialog();
                ApplyChanges();
            }
        }

        private void button30_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button30).ShowDialog();
                ApplyChanges();
            }
        }

        private void button31_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button31).ShowDialog();
                ApplyChanges();
            }
        }

        private void button32_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button32).ShowDialog();
                ApplyChanges();
            }
        }

        private void button33_Click(object sender, EventArgs e)
        {
            if (isKeyboardLoad)
            {
                new EditSymbol(ref button33).ShowDialog();
                ApplyChanges();
            }
        }

        private void phoneModelCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.currentProfile = phoneModelCombo.Items[phoneModelCombo.SelectedIndex] as PhoneModelProfile;
        }
    }

    public class ErrorLogger
    {
        private List<string> Log = new List<string>();

        public void AddError(string text, Exception ex)
        {
            if (!string.IsNullOrEmpty(text))
                Log.Add(DateTime.Now + ": \"" + text + "\"" + Environment.NewLine + "Тип ошибки: " + ex.ToString() + Environment.NewLine + "Текст ошибки: " + ex.Message);
            else
                Log.Add(DateTime.Now + ": \"Текст ошибки отсутствует!\"" + Environment.NewLine + "Тип ошибки: " + ex.ToString() + Environment.NewLine + "Текст ошибки: " + ex.Message);
            MessageBox.Show(text);
        }

        public void WriteLog()
        {
            DateTime now = DateTime.Now;
            if (!File.Exists(Application.StartupPath + "\\log.txt"))
                File.AppendAllText(Application.StartupPath + "\\log.txt", "Лог ошибок NFC");
            File.AppendAllText(Application.StartupPath + "\\log.txt", "-------------- " + now.ToString() + " --------------" + Environment.NewLine);
            foreach (string s in Log)
                File.AppendAllText(Application.StartupPath + "\\log.txt", s + Environment.NewLine);
        }

        public int GetErrorCount()
        {
            return Log.Count;
        }

        public override string ToString()
        {
            string result = string.Empty;
            foreach (string s in Log)
                result += "File missed: " + s + Environment.NewLine;
            return result;
        }
    }

    public class ConfigInfo
    {
        #region Fields
        private readonly string path;
        private Dictionary<string, bool> checkBoxSettings = new Dictionary<string, bool>();
        private Dictionary<string, object> comboBoxSettings = new Dictionary<string, object>();
        private Dictionary<string, string[]> textBoxSettings = new Dictionary<string, string[]>();
        private Dictionary<string, decimal> numericUpDownSettingd = new Dictionary<string, decimal>();
        private Dictionary<string, bool> radioButtonSettings = new Dictionary<string, bool>();
        private Dictionary<string, object[]> checkedListBoxSettings = new Dictionary<string, object[]>();
        private Dictionary<string, string> pathSettings = new Dictionary<string, string>();
        #endregion

        private Form1 form;
        private TabControl control;
        private ErrorLogger log;

        public ConfigInfo(Form1 f, TabControl c, ErrorLogger l)
        {
            this.form = f;
            this.control = c;
            this.log = l;
            path = Application.StartupPath + "\\Config\\";
        }

        public void InitConfigInfo()
        {
            foreach (Control cont in control.Controls)
            {
                foreach (Control c in cont.Controls)
                {
                    if (c.GetType() == typeof(CheckBox))
                        checkBoxSettings.Add(c.Name, (c as CheckBox).Checked);
                    if (c.GetType() == typeof(ComboBox))
                        comboBoxSettings.Add(c.Name, (c as ComboBox).SelectedItem);
                    if (c.GetType() == typeof(TextBox))
                        textBoxSettings.Add(c.Name, (c as TextBox).Lines);
                    if (c.GetType() == typeof(NumericUpDown))
                        numericUpDownSettingd.Add(c.Name, (c as NumericUpDown).Value);
                    if (c.GetType() == typeof(RadioButton))
                        radioButtonSettings.Add(c.Name, (c as RadioButton).Checked);
                    if (c.GetType() == typeof(CheckedListBox))
                    {
                        CheckedListBox.CheckedItemCollection coll = (c as CheckedListBox).CheckedItems;
                        object[] items = new object[coll.Count];
                        for (int i = 0; i < coll.Count; i++)
                            items[i] = coll[i];
                        checkedListBoxSettings.Add(c.Name, items);
                    }
                }
            }
            pathSettings.Add("effect", form.effectsFolderPath);
            pathSettings.Add("patch", form.patchesFolderPath);
            pathSettings.Add("font", form.fontFolderPath);
        }

        public void SaveConfig()
        {
            SerializeDictionary<string, bool>(path + "cb.dat", checkBoxSettings);
            SerializeDictionary<string, object>(path + "cmb.dat", comboBoxSettings);
            SerializeDictionary<string, string[]>(path + "tb.dat", textBoxSettings);
            SerializeDictionary<string, decimal>(path + "nud.dat", numericUpDownSettingd);
            SerializeDictionary<string, bool>(path + "rb.dat", radioButtonSettings);
            SerializeDictionary<string, object[]>(path + "clb.dat", checkedListBoxSettings);
            SerializeDictionary<string, string>(path + "p.dat", pathSettings);
        }

        public void LoadConfig()
        {
            checkBoxSettings = DeserializeDictionary<string, bool>(path + "cb.dat");
            comboBoxSettings = DeserializeDictionary<string, object>(path + "cmb.dat");
            textBoxSettings = DeserializeDictionary<string, string[]>(path + "tb.dat");
            numericUpDownSettingd = DeserializeDictionary<string, decimal>(path + "nud.dat");
            radioButtonSettings = DeserializeDictionary<string, bool>(path + "rb.dat");
            checkedListBoxSettings = DeserializeDictionary<string, object[]>(path + "clb.dat");
            pathSettings = DeserializeDictionary<string, string>(path + "p.dat");

            ApplyConfig();
        }

        private void ApplyConfig()
        {
            foreach (Control cont in control.Controls)
            {
                foreach (Control c in cont.Controls)
                {
                    if (checkBoxSettings.ContainsKey(c.Name))
                        (c as CheckBox).Checked = checkBoxSettings[c.Name];
                    if (comboBoxSettings.ContainsKey(c.Name))
                        (c as ComboBox).SelectedItem = comboBoxSettings[c.Name];
                    if (textBoxSettings.ContainsKey(c.Name))
                        (c as TextBox).Lines = textBoxSettings[c.Name];
                    if (numericUpDownSettingd.ContainsKey(c.Name))
                        (c as NumericUpDown).Value = numericUpDownSettingd[c.Name];
                    if (radioButtonSettings.ContainsKey(c.Name))
                        (c as RadioButton).Checked = radioButtonSettings[c.Name];
                    if (checkedListBoxSettings.ContainsKey(c.Name))
                    {
                        for (int j = 0; j < (c as CheckedListBox).Items.Count; j++)
                            (c as CheckedListBox).SetItemChecked(j, false);
                        foreach (object o in checkedListBoxSettings[c.Name])
                        {
                            for (int i = 0; i < (c as CheckedListBox).Items.Count; i++)
                            {
                                string tmp = (c as CheckedListBox).Items[i].ToString();
                                if (tmp == o.ToString())
                                    (c as CheckedListBox).SetItemChecked(i, true);
                            }
                        }
                    }
                }
            }
            form.fontFolderPath = pathSettings["font"];
            form.patchesFolderPath = pathSettings["patch"];
            form.effectsFolderPath = pathSettings["effect"];
        }

        public void ClearConfigClass()
        {
            checkBoxSettings.Clear();
            comboBoxSettings.Clear();
            textBoxSettings.Clear();
            numericUpDownSettingd.Clear();
            radioButtonSettings.Clear();
            checkedListBoxSettings.Clear();
            pathSettings.Clear();
        }

        public bool Modifed(Control c)
        {
            if (c.GetType() == typeof(CheckBox))
                return checkBoxSettings[c.Name].Equals((c as CheckBox).Checked);
            if (c.GetType() == typeof(ComboBox))
            {
                string left = comboBoxSettings[c.Name].ToString();
                string right = (c as ComboBox).SelectedItem.ToString();
                return left.Equals(right);
            }
            if (c.GetType() == typeof(TextBox))
            {
                bool res = true;
                string[] left = textBoxSettings[c.Name];
                string[] right = (c as TextBox).Lines;
                if (left.Length == right.Length)
                {
                    for (int i = 0; i < left.Length; i++)
                    {
                        if (!left[i].Equals(right[i]))
                        {
                            res = false;
                            break;
                        }
                    }
                    return res;
                }
                else
                    return false;
            }
            if (c.GetType() == typeof(NumericUpDown))
                return numericUpDownSettingd[c.Name].Equals((c as NumericUpDown).Value);
            if (c.GetType() == typeof(RadioButton))
                return radioButtonSettings[c.Name].Equals((c as RadioButton).Checked);
            if (c.GetType() == typeof(CheckedListBox))
            {
                CheckedListBox.CheckedItemCollection coll = (c as CheckedListBox).CheckedItems;
                object[] items = new object[coll.Count];
                for (int i = 0; i < coll.Count; i++)
                    items[i] = coll[i];
                bool res = true;
                if (items.Length == checkedListBoxSettings[c.Name].Length)
                {
                    for (int i = 0; i < items.Length; i++)
                    {
                        string left = items[i].ToString();
                        string right = checkedListBoxSettings[c.Name][i].ToString();
                        if (!left.Equals(right))
                        {
                            res = false;
                            break;
                        }
                    }
                    return res;
                }
                else
                    return false;
            }
            return false;
        }

        private void SerializeDictionary<TKey, TValue>(string sFileName, Dictionary<TKey, TValue> Dict)
        {
            var SaveList = new List<DictItem<TKey, TValue>>();
            foreach (TKey Key in Dict.Keys)
                SaveList.Add(new DictItem<TKey, TValue> { Key = Key, Value = Dict[Key] });

            XmlSerializer serializer = new XmlSerializer(typeof(List<DictItem<TKey, TValue>>));
            try
            {
                TextWriter Writer = new StreamWriter(sFileName);
                serializer.Serialize(Writer, SaveList);
                Writer.Close();
            }
            catch (Exception ex)
            {
                log.AddError("При сохранении настроек произошла ошибка!", ex);
            }
        }

        private Dictionary<TKey, TValue> DeserializeDictionary<TKey, TValue>(string sFileName)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<DictItem<TKey, TValue>>));
            try
            {
                FileStream fs = new FileStream(sFileName, FileMode.Open);
                var LoadList = (List<DictItem<TKey, TValue>>)serializer.Deserialize(fs);
                fs.Close();
                var LoadDict = new Dictionary<TKey, TValue>();
                foreach (DictItem<TKey, TValue> Item in LoadList)
                    LoadDict.Add(Item.Key, Item.Value);
                return LoadDict;
            }
            catch (Exception ex)
            {
                log.AddError("Произошла ошибка при открытии файла настроек.",ex);
                return new Dictionary<TKey, TValue>();
            }
        }
    }

    public class DictItem<TKey, TValue>
    {
        public TKey Key;
        public TValue Value;
    }

    public class Profile
    {
        public string profileName;

        public override string ToString()
        {
            return profileName;
        }
    }

    public class PerfomanceProfile : Profile
    {
        public decimal heapSize;
        public decimal progLatency;
        public decimal fps;
        public decimal maxCacheObjects;
        public decimal cpuTime;
        public decimal resCacheSize;
        public decimal effectsDiff;
        public decimal sysCacheSize;
        public decimal bufferPercent;

        public bool increaseDiskCacheSize;
        public bool disableCameraAppCaching;
        public bool cleanAutorun;
        public bool sysCacheOnC;
    }

    public class KineticProfile : Profile
    {
        public decimal one;
        public decimal two;
        public decimal three;
        public decimal four;
        public decimal five;
        public decimal six;
        public decimal seven;
        public decimal eight;
    }

    public class PhoneModelProfile : Profile
    {
        //Стартеры для очистки автозагрузки и для автозагрузки ромпатчера
        public string autorun;
        //Файл для отключения сообщения о переадресации
        public string phoneUi;
        //Папка с украинским вводом
        public string ukr;
        //Папка с русским вводом
        public string rus;
    }
}